Zważ swoje słowa!

10

Wyzwanie

Biorąc pod uwagę dwa ciągi, każdy o długości do 30, składające się z drukowalnych znaków ASCII (kody [32,126]), umieść je na skali wagi w jak najmniejszej liczbie bajtów kodu! Składa się z następujących kroków:

  1. Oblicz i porównaj wagi strun
  2. Wybierz odpowiednio pochyloną skalę ASCII-art
  3. Umieść dwa ciągi na wadze

Ciągi mogą być przekazywane jako tablica, dwa argumenty lub dowolna inna rozsądna metoda.


Ciężar łańcucha jest zdefiniowany jako suma mas znaków tego łańcucha, gdzie:

  • Spacje mają wagę 0 ( )
  • Małe litery mają wagę 2 ( abcdefghijklmnopqrstuvwxyz)
  • Wielkie litery mają wagę 4 ( ABCDEFGHIJKLMNOPQRSTUVWXYZ)
  • Wszystkie pozostałe symbole mają wagę 3 ( !"#$%&'()*+,-./0123456789:;<=>?@[\]^_`{|}~)

Skale wyglądają następująco:

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

Jeśli pierwszy ciąg jest cięższy, użyj pierwszego rysunku jako podstawy wyników; jeśli drugi ciąg jest cięższy, użyj drugiego rysunku; jeśli struny mają równą wagę, użyj trzeciego. Końcowe białe znaki są dozwolone.


Będę używał segmentu trzeciego rysunku jako podstawy dla wszystkich poniższych przykładów.

Pierwszy sznurek należy umieścić na lewej szalce, a drugi sznur na prawej szalce.

Umieść ciąg na patelni, umieszczając jego znaki spacji w obszarze 6x5 bezpośrednio nad kreskami, jak zaznaczono #tutaj s (możesz w końcu nadpisać część skali równowagi - to dobrze):

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

Wszystkie te postacie powinny być „rozliczone”, tj. powyżej -znaku lub innego znaku z ciągu:

  ŹLE ŹLE PRAWIDŁOWO
    ____ ____ ____
 f / \ / \ / \
  l \ / \ / \
 / \ / hov \ / s \
/ oating \ / eri ng \ / ettled \
* ------ * * ------ * * ------ *

Ponadto cały stos powinien być możliwie jak najbardziej płaski, co oznacza, że ​​z sześciu kolumn o szerokości 1 wysokość najwyższego i najkrótszego nie może różnić się więcej niż o 1:

    ŹLE ŹLE POPRAWNIE POPRAWNIE
[najwyższy: 5] [najwyższy: 4] [najwyższy: 5] [najwyższy: 2]
[najkrótszy: 0] [najkrótszy: 2] [najkrótszy: 4] [najkrótszy: 2]
      5__5_ ____ 5_5__ ____
     45445 i / \ 445454 / \
     45445 $% i $ @ 445454 / \
    / 45445 i% @% $ i 445454% i $ @% &
   / 45445 \ / & $ @ $ &% \ / 445454 \ / $ @ $% $$ \
   * ------ * * ------ * * ------ * * ------ *

Dokładna kolejność / układ znaków nie ma znaczenia. Poniżej przedstawiono wszystkie poprawne ustalenia dla ciągu „Zważ swoje słowa!”:

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

Przypadki testowe

WEJŚCIE: „KOD GOLF”, „wyzwania kodowania”
WAGA: 32, 32
PRZYKŁADOWE WYJŚCIE:
          . 
          |
    ______ | ______
   / \ | / \
  / \ | nge \ s
 / OO \ | mały
/ CFGLED \ | /kodowanie\
* ------ * | * ------ *
          |
          |
    ______ | ______ 
WEJŚCIE: „”, „$”
WAGA: 0, 3
PRZYKŁADOWE WYJŚCIE:
    _.
   / \ * -_ |
  / \ * - |
 / \ | * -_ 
/ \ | * -_
* ------ * | / \
          | / \
          | / \
          | / $ \
          | * ------ *
    ______ | ______
WEJŚCIE: „WIESZ CO MÓWIĄ!”, „There_always_a_relevant_xkcd”
WAGA: 75, 65
PRZYKŁADOWE WYJŚCIE:
          . tr_a_s
          | _hekx_y
          | - * elcdta
       _- * | revanw
    _- * | / e's_al \
  T / \ | * ------ *
 AUYOHY |
 A! HWYK |
/ OTSMEW \ |
* ------ * |
    ______ | ______
ujemna siódemka
źródło
1
Czy dopuszczalne są końcowe białe znaki?
Hiatsu
@Hiatsu Tak, w porządku.
negatywne siedem
2
Lubię to wyzwanie, naprawdę mi się podoba. Są jednak 2 punkty, które uniemożliwiają mi to +1. Po pierwsze: jeśli przestrzenie nic nie „ważą” i nie zostają uwzględnione w grafice, to po co w ogóle je uwzględniać? To po prostu niepotrzebne obciążenie, aby je najpierw odfiltrować. Po drugie: dla mnie jest to wyzwanie „2 w 1” / kameleon - Wyzwanie 1: Określ, który łańcuch jest „cięższy”, Wyzwanie 2: Wygeneruj trochę sztuki ASCII.
Shaggy
@Shaggy Myślę, że to uczciwa ocena. Publikowanie tego nauczyło mnie po prostu prostoty.
negatywne siedem

Odpowiedzi:

7

Węgiel drzewny , 110 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Pobiera dane wejściowe jako tablicę dwóch ciągów. Wyjaśnienie:

UMθ⪫⪪ι ω

Usuń spacje z obu ciągów.

≔⁰η

Załóż równowagę wag.

Fθ

Zapętlić obie struny.

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

Odejmij różnicę biegu od ciężaru łańcucha.

P-×⁷_↑χ.¶¶

Wydrukuj podstawę wagi.

≔³ζ

Załóż, że oba patelnie znajdują się 3 nad ziemią.

¿η«

Jeśli ciężary się nie równoważą ...

≔∨›⁰η⁵ζ

... obliczyć wysokość lewej patelni ...

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

... narysuj wagę pochylając się w prawo ...

¿›⁰η‖»

... i zastanów się, czy lewa patelnia była cięższa.

P-⁺|×⁶_

W przeciwnym razie narysuj równowagę poziomu.

J±⁴±ζ

Przejdź do szalki na pierwszą skalę.

Fθ«

Pętla nad wejściami.

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

Narysuj szalkę wagi.

←⪪ι⁶

Przekrój materiał wejściowy na podciągi o długości 6 i wydrukuj go do góry nogami, aby wypełnili miskę do góry.

J⁹⁻ζ⁶

Przejdź do szalki drugiej skali.

Neil
źródło
6

Python 2 , 1101 1071 855 837 bajtów

-216 bajtów z kompresją ciągów

-18 bajtów poprzez zmniejszenie niektórych powtórzeń

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))

Wypróbuj online!

Uruchom jako A(string_one, string_two.

w oblicza rekurencyjnie wagę ciągu.

t to skompresowany i z przeplotem tekst wszystkich sześciu możliwych skal, który bardzo dobrze się kompresuje.

p pobiera ciąg znaków (z usuniętymi spacjami), wagę ciągu i bok wagi, na którym znajduje się ciąg, i tworzy blok znaków 5 x 6.

Abierze łańcuchy i buduje ich bloki p. Olbrzymi ciąg na dole to trzy ciągi formatu z przeplotem i skompresowane.

Hiatsu
źródło
3

JavaScript (ES6),  340  337 bajtów

Pobiera dane wejściowe jako tablicę 2 tablic znaków. Rysuje znak wyjściowy po znaku.

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)

Wypróbuj online!

W jaki sposób?

Definiujemy pierwszą funkcję pomocniczą, która usuwa spacje z ciągu wejściowego S.[ja] i zwraca swoją wagę:

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
)                            //

NB: Ponieważ ponownie wykorzystujemy ja aby obliczyć wagę, jest wyłączony o jeden za S.[1].

Obliczamy s, co jest równe 0 gdyby S.[0] jest cięższy 2) gdyby S.[1] jest cięższy lub 1 jeśli oba ciągi mają taką samą wagę:

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

Teraz wywołujemy drugą funkcję pomocniczą, aby narysować wynik:

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

Gdzie INDEXoblicza się w następujący sposób:

~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
źródło
1

Java 10, 1043 993 988 983 bajtów

(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 bajtów dzięki @ceilingcat .

Dane wejściowe to dwa ciągi, które w rezultacie będą skutkować macierzą znaków.

Wypróbuj online.

Wyjaśnienie:

// 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
źródło