Timbang kata-kata Anda!

10

Tantangan

Diberikan dua string, masing-masing panjangnya hingga 30, terdiri dari karakter ASCII yang dapat dicetak (kode [32,126] ), menempatkan mereka ke skala keseimbangan dalam byte kode paling sedikit! Ini terdiri dari langkah-langkah berikut:

  1. Hitung dan bandingkan bobot senar
  2. Pilih skala ASCII-art yang dimiringkan dengan tepat
  3. Tempatkan kedua string ke skala

String dapat diteruskan sebagai array, dua argumen, atau metode masuk akal lainnya.


The berat string didefinisikan sebagai jumlah dari bobot karakter string, di mana:

  • Spasi memiliki bobot 0 ( )
  • Huruf kecil memiliki bobot 2 (abcdefghijklmnopqrstuvwxyz )
  • Huruf besar memiliki berat 4 (ABCDEFGHIJKLMNOPQRSTUVWXYZ )
  • Semua simbol lainnya memiliki berat 3 ( !"#$%&'()*+,-./0123456789:;<=>?@[\]^_`{|}~)

Timbangannya terlihat seperti ini:

          . _
          | _- * / \
          | - * / \
       _- * | / \
    _- * | / \
   / \ | * ------ *
  / \ |
 / \ |
/ \ |
* ------ * |
    ______ | ______
    _.
   / \ * -_ |
  / \ * - |
 / \ | * -_ 
/ \ | * -_
* ------ * | / \
          | / \
          | / \
          | / \
          | * ------ *
    ______ | ______
          .
          |
    ______ | ______
   / \ | / \
  / \ | / \
 / \ | / \
/ \ | / \
* ------ * | * ------ *
          |
          |
    ______ | ______

Jika string pertama lebih berat, gunakan gambar pertama sebagai basis output Anda; jika string kedua lebih berat, gunakan gambar kedua; jika senar memiliki bobot yang sama, gunakan yang ketiga. Trailing whitespace diizinkan.


Saya akan menggunakan segmen gambar ketiga sebagai dasar untuk semua contoh berikut.

Tali pertama harus diletakkan di atas loyang kiri, dan tali kedua di loyang kanan.

Tempatkan string pada panci dengan menempatkan karakter non-spasi di dalam area 6x5 tepat di atas tanda hubung, seperti yang ditandai oleh #s di sini (Anda mungkin akhirnya menimpa bagian dari skala keseimbangan - yang baik-baik saja):

 ###### _
 ######
 ######
 ######
/ ###### \
* ------ *

Semua karakter ini harus "diselesaikan" yaitu. baik di atas -karakter atau karakter lain dari string:

  SALAH SALAH BENAR
    ____ ____ ____
 f / \ / \ / \
  l \ / \ / \
 / \ / hov \ / s \
/ oating \ / eri ng \ / ettled \
* ------ * * ------ * * ------ *

Selain itu, seluruh tumpukan harus serata mungkin, artinya dari keenam kolom selebar 1, tinggi tertinggi dan tinggi paling pendek tidak boleh berbeda lebih dari 1:

    SALAH SINGKAT BENAR
[tertinggi: 5] [tertinggi: 4] [tertinggi: 5] [tertinggi: 2]
[terpendek: 0] [terpendek: 2] [terpendek: 4] [terpendek: 2]
      5__5_ ____ 5_5__ ____
     45445 & / \ 445454 / \
     45445 $% & $ @ 445454 / \
    / 45445 &% @% $ & 445454% & $ @% &
   / 45445 \ / & $ @ $ &% \ / 445454 \ / $ @ $% $$ \
   * ------ * * ------ * * ------ * * ------ *

Urutan / pengaturan karakter yang tepat tidak masalah. Berikut ini adalah semua pengaturan yang valid untuk string "Timbang kata-kata Anda!":

    ____ ____ ____ ____
   / \ / \ / \ / \
 ds! \ / owd oe \ u! Wd \
 ourwor Wihuos yoiwgr eghioo
/ Timbang \ / egyrr! \ / Wrhd! S \ / rrsuwy \
* ------ * * ------ * * ------ * * ------ *

Uji kasus

INPUT: "CODE GOLF", "tantangan coding"
BERAT: 32, 32
CONTOH OUTPUT:
          . 
          |
    ______ | ______
   / \ | / \
  / \ | nge
 / OO \ | challe
/ CFGLED \ | / coding \
* ------ * | * ------ *
          |
          |
    ______ | ______ 
INPUT: "", "$"
BERAT: 0, 3
CONTOH OUTPUT:
    _.
   / \ * -_ |
  / \ * - |
 / \ | * -_ 
/ \ | * -_
* ------ * | / \
          | / \
          | / \
          | / $ \
          | * ------ *
    ______ | ______
INPUT: "KAU TAHU APA YANG MEREKA KATAKAN!", "There_always_a_relevant_xkcd"
BERAT: 75, 65
CONTOH OUTPUT:
          . tr_a_s
          | _hekx_y
          | - * elcdta
       _- * | Revanw
    _- * | / e's_al \
  T / \ | * ------ *
 AUYOHY |
 A! HWYK |
/ OTSMEW \ |
* ------ * |
    ______ | ______
negatif tujuh
sumber
1
Apakah trailing whitespace dapat diterima?
Hiatsu
@Hiatsu Yap, tidak apa-apa.
negatif tujuh
2
Saya suka tantangan ini, saya benar-benar melakukannya. Namun ada 2 poin yang mencegah saya memberikannya +1. Pertama: jika ruang tidak "menimbang" apa pun dan tidak dimasukkan ke dalam karya seni lalu mengapa menyertakannya sama sekali? Hanya overhead yang tidak perlu untuk menyaring mereka terlebih dahulu. Kedua: ini terasa seperti tantangan "2-in-1" / bunglon bagi saya - Tantangan 1: Tentukan string mana yang "lebih berat", Tantangan 2: Hasilkan beberapa seni ASCII.
Shaggy
@ Shaggy Saya pikir itu penilaian yang adil. Posting ini telah mengajari saya untuk menjaga hal-hal sederhana.
negatif tujuh

Jawaban:

7

Arang , 110 byte

UMθ⪫⪪ι ω≔⁰ηFθ≦⁻ΣEι⁻⁺³№ακ№βκηP-×⁷_↑χ.¶¶≔³ζ¿η«≔∨›⁰η⁵ζM±⁶±²_F⁴⁺¶*-§_|_ι¿›⁰η‖»P-⁺|×⁶_J±⁴±ζFθ«←⁶↑*↗⁴↓↘⁴←↖*←⪪ι⁶J⁹⁻ζ⁶

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Mengambil input sebagai array dari dua string. Penjelasan:

UMθ⪫⪪ι ω

Hapus spasi dari kedua string.

≔⁰η

Asumsikan keseimbangan bobot.

Fθ

Ulangi kedua dawai.

≦⁻ΣEι⁻⁺³№ακ№βκη

Kurangi perbedaan lari dari bobot tali.

P-×⁷_↑χ.¶¶

Cetak dasar skala keseimbangan.

≔³ζ

Asumsikan bahwa kedua panci adalah 3 dari tanah.

¿η«

Jika bobot tidak seimbang ...

≔∨›⁰η⁵ζ

... hitung ketinggian wajan kiri ...

M±⁶±²_F⁴⁺¶*-§_|_ι

... menggambar keseimbangan condong ke kanan ...

¿›⁰η‖»

... dan mencerminkan jika panci kiri lebih berat.

P-⁺|×⁶_

Kalau tidak, tarik keseimbangan level.

J±⁴±ζ

Lompat ke panci skala pertama.

Fθ«

Ulangi input.

←⁶↑*↗⁴↓↘⁴←↖*

Gambarkan panci skala.

←⪪ι⁶

Iris input ke dalam substring dengan panjang 6 dan cetak terbalik sehingga mengisi panci ke atas.

J⁹⁻ζ⁶

Lompat ke panci skala kedua.

Neil
sumber
6

Python 2 , 1101 1071 855 837 byte

-216 byte dengan kompresi string

-18 byte dengan mengurangi beberapa pengulangan

from zlib import decompress as Z
from base64 import b64decode as D
r=range(6)
j="".join
w=lambda a:0if not a else(2+2*(a[0]<'[')if a[0].isalpha()else 3)+w(a[1:])
t=Z(D('eJxT0FKIV1BQ0AWT8SAIJsAcXTCppQAGumBSSx8MYsBAC0kCAiCySAIKEJW4ZHGpxA8AejMemQ=='))
p=lambda k,l,m:j(map(j,[(t[2*l+m::6][:30-len(k)]+k)[i::6]for i in r]))
def A(a,b):
 e=cmp(w(j(a.split())),w(j(b.split())))+1;return Z(D('eJxVUUGuhTAI3HOKWTdBW/U2SHoQ4O6ftvrMb0hLZJgZAYABFZB5KxD4zrZtNJOJMaHWIIoa0D6Ao+jrWRiHEI7kMcQg9VLBCo9O3dCbdanepOvZQztF9rRH2xUlwISehIZ96HltLFqu1IMF2p1QH/S+1Ge7CT5blIVOxqUWFudjqHPSwhitjPbzf7uZ1HaIaG2hShFTfU7Eca6J7MBr1K+3/YbRVLd2VlE5oilp7EG/gV7+DPQuSAsZPm7PZE9HBY2G+ctS/QzR+whSGlPAGz4mkkl5Sf18SMvkyL9iF6aLd2WLUm/KDVzvJu93k2tLZXlwetgLmFH4MzcKCaJnqX1Fz3iOf4//Pi7EwP4BHmyJpg=='))[e::3].format(*map(lambda c:[p(j(([a,b]*3)[c].split()),e,c)[i::5]for i in r],r))

Cobalah online!

Jalankan sebagai A(string_one, string_two.

w menghitung berat string secara rekursif.

t adalah teks terkompresi dan interlaced dari semua enam skala yang mungkin, yang terjadi untuk mengompresi dengan sangat baik.

p mengambil string (dengan spasi dihilangkan), bobot string, dan sisi keseimbangan string yang aktif, dan menciptakan blok karakter 5x6.

Amengambil string, dan membangun blok mereka dengan p. String raksasa di bagian bawah adalah tiga format string yang saling terkait dan terkompresi.

Hiatsu
sumber
3

JavaScript (ES6),  340  337 byte

Mengambil input sebagai array dari 2 array karakter. Menarik karakter keluaran dengan karakter.

S=>(s=Math.sign(~(g=i=>(S[i]=S[i].filter(c=>c>' '?i+=/[a-z]/gi.test(c)?c>{}?2:4:3:0),i))(0)+g(1))+1,g=x=>y>10?'':(X=(r=x>9)?20-x:x,Y=(r?2-s:s)*2+y,S[+r][X>0&&X<7&&47-Y*6+X]||`. /\\|-_*
`[~X?x-10?y>9?X>3?6:1:[x+y*3-17,2*y-4,x+~y*3][s]/2|X<4?Y<5|Y>8?Y-9|X>7?1:X%7?5:7:~X+Y?X+Y-8?1:2^r:3^r:[7-x%3,6,5+x%3][s]:y&&4:8])+g(x<21?x+1:!++y))(y=0)

Cobalah online!

Bagaimana?

S[i]

g = i => (                   // i = string index
  S[i] = S[i].filter(c =>    // for each character c in S[i]:
    c > ' ' ?                //   if c is not a space:
      i +=                   //     update i:
        /[a-z]/gi.test(c) ?  //       if c is a letter:
          c > {} ?           //         if c is in lower case:
            2                //           add 2 to i
          :                  //         else:
            4                //           add 4 to i
        :                    //       else (not a letter):
          3                  //         add 3 to i
    :                        //   else (a space):
      0                      //     remove c from S[i]
  ), i                       // end of filter(); return i
)                            //

iS[1]

s0S[0]2S[1]1

s = Math.sign(~g(0) + g(1)) + 1

Kami sekarang memanggil fungsi pembantu kedua untuk menggambar output:

g = x =>                     // given x:
  y > 10 ?                   //   if we've reached the last row:
    ''                       //     stop recursion
  :                          //   else:
    ( X = (r = x > 9) ?      //     r = true if we're on the right side
        20 - x               //       X = 20 - x on the right side
      :                      //     or:
        x,                   //       X = x on the left side
      Y = (r ? 2 - s : s)    //     Y is the position of the scale tray
          * 2 + y,           //     according to s and the current side
      S[+r][                 //     we try to extract a character from S[0] or S[1]:
        X > 0 && X < 7 &&    //       provided that we're located above the tray
        47 - Y * 6 + X       //       and using an index based on (X, Y)
      ] ||                   //     if this character doesn't exist,
      `. /\\|-_*\n`[INDEX]   //     we need to draw the balance instead
    ) +                      //     (see the next part)
    g(x < 21 ? x + 1 : !++y) //     append the result of a recursive call

Di mana INDEXdihitung sebagai berikut:

~X ?                         // if this is not the last character of the current row:
  x - 10 ?                   //   if this is not the central column:
    y > 9 ?                  //     if this is the last row:
      X > 3 ? 6 : 1          //       draw the base ('_' or a space)
    :                        //     else:
      [ x + y * 3 - 17,      //       attempt to draw the beam:
        2 * y - 4,           //         using an equation depending on s
        x + ~y * 3           //         whose result must be -1, 0 or 1
      ][s] / 2 | X < 4 ?     //       if it's invalid or X is less than 4:
        Y < 5 | Y > 8 ?      //         if we're not over the chains:
          Y - 9 | X > 7 ?    //           if we're not over the pan:
            1                //             draw a space
          :                  //           else:
            X % 7 ? 5 : 7    //             draw the pan ('-' or '*')
        :                    //         else:
          ~X + Y ?           //           if this is not an interior chain:
            X + Y - 8 ?      //             if this is not an exterior chain:
              1              //               draw a space
            :                //             else:
              2 ^ r          //               draw the exterior chain ('/' or '\')
          :                  //           else:
            3 ^ r            //             draw the interior chain ('/' or '\')
      :                      //       else:
        [ 7 - x % 3,         //         draw the beam, using either '_' -> '-' -> '*'
          6,                 //         or just '_'
          5 + x % 3          //         or '*' -> '-' -> '_'
        ][s]                 //         depending on s
  :                          //   else:
    y && 4                   //     draw the central pillar ('|' or '.')
:                            // else:
  8                          //   append a line feed
Arnauld
sumber
1

Java 10, 1043 993 988 983 byte

(a,b)->{var r=new char[11][21];for(var A:r)java.util.Arrays.fill(A,' ');a=a.replace(" ","");b=b.replace(" ","");int A=s(a),B=s(b),j,c,i=3;for(;++i<17;r[3][i]=A==B?'_':32)r[10][i]=95;for(i=11;i-->1;)r[i][10]=i>0?'|':46;if(A==B){r[8][0]=r[8][7]=r[8][13]=r[8][20]=42;for(i=0;++i<20;)if(i<8|i>13)r[8][i]=45;for(i=8;i-->4;r[i][7-i]=r[i][20-i]=47)r[i][i]=r[i][i+13]=92;A=B=8;}else{r[5][i=A<B?0:13]=r[5][i+7]=r[9][13-i]=r[9][20-i]=42;for(i=5;i-->1;r[i][A>B?18-i*3:2+i*3]=42)r[i][A>B?17-i*3:3+i*3]=45;for(i=0;++i<20;)r[i>13?A>B?5:9:A>B?9:5][i>13|i<7?i:1]=45;for(i=9;i-->1;r[i][i>4?A>B?8-i:21-i:A>B?17-i:4-i]=47)r[i][i>4?A>B?i-1:i+12:A>B?i+16:i+3]=92;A=(A>B?r[i=0][16]=r[1][13]=r[3][7]=r[4][4]=95:(r[0][i=4]=r[1][7]=r[3][13]=r[4][16]=95));A=9-i;B=5+i;}c(r,a,A,7);c(r,b,B,20);return r;};int s(String s){int r=0;for(int i:s.getBytes())r+=i>64&i<91?4:i>96&i<123?2:3;return r;}void c(char[][]r,String s,int p,int q){for(int c=0,i=p,j;i-->p-5;)for(j=q;j-->q-6&c<s.length();)r[i][j]=s.charAt(c++);}

-5 byte terima kasih kepada @ceilingcat .

Input adalah dua String, yang akan menghasilkan karakter-matriks sebagai hasilnya.

Cobalah online.

Penjelasan:

// Method with two String parameters and character-matrix return-type:
(a,b)->{
  // Result matrix, with 11 rows and 21 columns:
  var r=new char[11][21];
  // Initially fill the entire matrix with spaces:
  for(var A:r)java.util.Arrays.fill(A,' ');
  // Remove all spaces from the input-Strings:          
  a=a.replace(" ","");b=b.replace(" ","");
  // Call a separated method to calculate the scores of both input-Strings:
  int A=s(a),B=s(b),

  // Fill the cells for the base with '_',
  // and also fill the cells for the balance-bar with '_' when the scores are equal:
  j,c,i=3;for(;++i<17;r[3][i]=A==B?'_':32)r[10][i]=95;
  // Fill the cells for the stand with '|':
  for(i=11;i-->1;)r[i][10]=i>0?'|'
  // And the top of it with '.':
  :46;

  // If the scores are equal:
  if(A==B){
    // Fill the four appropriate cells for the sides of the scales with '*':
    r[8][0]=r[8][7]=r[8][13]=r[8][20]=42;
    // Fill the appropriate cells for the scales themselves with '-':
    for(i=0;++i<20;)if(i<8|i>13)r[8][i]=45;
    // Fill the appropriate cells of the robes with '/' and '\':
    for(i=8;i-->4;r[i][7-i]=r[i][20-i]=47)r[i][i]=r[i][i+13]=92;
    // Set A and B both to 8 to use later on:
    A=B=8;}
  // If the scores aren't equal:
  else{
    // Fill the four appropriate cells for the sides of the scales with '*':
    r[5][i=A<B?0:13]=r[5][i+7]=r[9][13-i]=r[9][20-i]=42;
    // Fill the appropriate four cells of the balance-bar with '-':
    for(i=5;i-->1;r[i][A>B?18-i*3:2+i*3]=42)r[i][A>B?17-i*3:3+i*3]=45;
    // Fill the appropriate cells of the scales with '-':
    for(i=0;++i<20;)r[i>13?A>B?5:9:A>B?9:5][i>13|i<7?i:1]=45;
    // Fill the appropriate cells of the robes with '/' and '\':
    for(i=9;i-->1;r[i][i>4?A>B?8-i:21-i:A>B?17-i:4-i]=47)r[i][i>4?A>B?i-1:i+12:A>B?i+16:i+3]=92;
    // Fill the four appropriate cells of the balance-bar with '_',
    // and set A and B to 9 and 5 depending on which score is higher:
    A=(A>B?r[i=0][16]=r[1][13]=r[3][7]=r[4][4]=95:(r[0][i=4]=r[1][7]=r[3][13]=r[4][16]=95));A=9-i;B=5+i;}
  // Call a separated method to fill the cells above the scales with the input-characters:
  c(r,a,A,7);c(r,b,B,20);
  // And finally return the resulting character-matrix:
  return r;};

// Separated method to calculate the score of the given String:
int s(String s){
  // Initially start the score-sum at 0:
  int r=0;
  // Loop over the characters of the given String:
  for(int i:s.getBytes())
    // Increase the sum by:
    r+=
      // 4 for uppercase letters:
      i>64&i<91?4
      // 2 for lowercase letters:
      :i>96&i<123?2
      // 3 for any other character:
      :3;
  // And return the resulting sum:
  return r;}

// Separated method to draw the strings on top of the scales:
void c(char[][]r,String s,int p,int q){
  // Keep a counter so we know when we're done drawing the given String:
  for(int c=0,
  // Loop over the appropriate rows bottom to top:
  i=p,j;i-->p-5;)
    // Inner loop over the appropriate cells of this row left to right,
    for(j=q;j-->q-6
    // as long as we're not done yet with the input-String:
        &c<s.length();)
      // And fill that appropriate cell with the next character in line of the given String:
      r[i][j]=s.charAt(c++);}
Kevin Cruijssen
sumber