Намалюйте стрункий рядок


26

( Натхненний цим викликом .)

Скажімо, у нас є рядок ABBCBA. Можна сказати, що між Aі B, як Bнаслідок A, існує підйом ; ми можемо сказати, що пробіг є між собою Bі Bнічого не змінюється; і, нарешті, ми можемо сказати, що падіння між Cі B. Ми можемо намалювати такий графік:

             A   B   B   C   B   A
Rising:        o       o
Continuing:        o
Falling:                   o   o

Без міток та мінімізації пробілів:

o o
 o
   oo

Це очікуваний вихід для введення ABBCBA.

Ви можете використовувати будь-який символ без пробілів для заміни oу висновку. Крім того, кожен стовпець необов'язково може мати додатковий простір між ними, наприклад:

o   o
  o 
      o o

Вхід буде складатися щонайменше з трьох символів. Рядок складається повністю з великих літер, але замість цього ви можете використовувати малі літери.

Тестові справи

TEST CASE
LINE 1
LINE 2
LINE 3

HELLOWORLD
 o oo o
  o
o    o oo

TESTCASE
 oo  o

o  oo o

EXAMINATION
o o o o o

 o o o o o

ZSILENTYOUTH
  o ooo o

oo o   o oo

ABC
oo



ABCBA
oo

  oo

Чи може бути пробіл між кожними послідовними osми, чи висновок повинен бути компактним?
JungHwan Min

@JHM Звичайно, це добре.
Conor O'Brien

Також, чи повинен виводити рядок, чи потрібно лише виглядати схожим на прикладі?
JungHwan Min

@JHM Що ти маєш на увазі?
Conor O'Brien

Код, який я маю на увазі, генерує сітку.
JungHwan Min

Відповіді:


6

Желе , 11 байт

OIṠ“ o ”ṙZY

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

OIṠ“ o ”ṙZY  Main link. Argument: s (string)

O            Ordinal; replace all characters with their code points.
 I           Increments; compute the differences of consecutive code points.
  Ṡ          Sign function.
   “ o ”ṙ    Rotate that string -1, 0, or 1 unit(s) to the left.
         Z   Zip; transpose rows and columns.
          Y  Join, separating by linefeeds.

11

Математика, 93 83 68 64 байт

(використовує 0, не O)

Row[Column@Insert[{,},0,2-#]&/@Sign@Differences@LetterNumber@#]&

Пояснення

LetterNumber@#

Визначає положення в алфавіті кожного символу вводу.

Sign@Differences@

Бере різницю між кожними послідовними елементами і приймає знак ( -1за негатив / падіння, 0за 0 / продовження, 1за позитив / підйом)

Insert[{,},0,2-#]&

Вставляє a 0у списку з двох Nulls, у першій позиції, якщо піднімається, середній, якщо триває, і третій позиції, якщо падає.

Row[Column@ ... ]

Форматує вихід.


Якщо висновок може виглядати інакше, ніж у запитанні, наведений вище код можна скоротити до 41 байта:

ListPlot@*Sign@*Differences@*LetterNumber

... що створює щось подібне (для "ABBCBA"):

введіть тут опис зображення


Як виглядає 41 байт?
Conor O'Brien

@ ConorO'Brien, будь ласка, дивіться редагувати.
JungHwan Min

10

MATL , 15 , 14 байт

dZSqtQtQv~79*c

Спробуйте в Інтернеті!

Пояснення:

Кажуть, що картина вартує тисячі слів, тому ось бета-онлайн-інтерпретатор, який показує вам значення на вершині стека в прямому ефірі під час оновлення. Зауважте, що він все ще знаходиться в бета-версії, тому вам може знадобитися кілька разів натиснути запуск.

Тож спочатку ми телефонуємо dZS. dдає нам різницю між кожним послідовним елементом і ZSдає нам знак (-1, 0 або 1) кожного елемента. Тож із введенням 'HELLOWORLD' після першого кроку ми матимемо:

-1  1  0  1  1 -1  1 -1 -1

Тепер ми просто використовуємо qдля декрементації цього і отримуємо:

-2  0 -1  0  0 -2  0 -2 -2

А потім два рази дублюємо верхню частину стека і збільшуємо масив ( tQ) Після цього у нас буде

-2  0 -1  0  0 -2  0 -2 -2
-1  1  0  1  1 -1  1 -1 -1
0   2  1  2  2  0  2  0  0

Тепер усі 0-ті, де ми хочемо вивести персонажа. Отже, ми з'єднуємо ці три масиви в матрицю ( v) і логічно заперечуємо її ( ~). Потім ми множимо кожне значення в матриці на значення ASCII 'O', ( 79*) і відображаємо його як рядок з c.


Коли у вас є вектор [-1, 1, 0, 1, ...], ви можете використовувати їх як індекси рядків розрідженої матриці з індексами стовпців [1,2,3,4, ...], то перетворити його в повну матрицю.
Нік Алгер

Гаразд ніколи не знаю, спробувавши цю пропозицію, схоже, нічого не врятувало
Нік Алгер

@NickAlger Все одно дякую за пораду! З цікавості я міг бачити, що ти придумав?
DJMcMayhem

Звичайно. Далі йде 19 символів, хоча це, можливо, було б покращено на кілька, dZS2 + tn: tnZ? XPg79 * c
Нік

Отримав це до 16 з парами оптимізацій, dZSqq_tn: lZ? 79 * c
Нік Алгер

8

Haskell, 63 байти

f w=[do(e,y)<-zip w$tail w;max" "['o'|b e y]|b<-[(<),(==),(>)]]

Повертає список з трьох рядків, що представляють лінії виводу. Не містить підсвідомих повідомлень.

dianne зберегла три байти, використовуючи doпозначення та maxзамість розуміння списку та last.


3
Чудово, він не містить підсвідомих повідомлень! Що це?
Conor O'Brien

5
['o'|b e y]..
izabera

Так, мій господар Зачекайте, що відбувається?
CalculatorFeline

7

CJam , 19 байт

l2ew{:-g)S3*0t}%zN*

Використовує 0замість o.

Спробуйте в Інтернеті!

Пояснення

l      e# Read input.
2ew    e# Get all pairs of consecutive letters.
{      e# Map this block over the pairs...
  :-   e#   Compute the difference between the two letters.
  g    e#   Signum. Gives -1 for rises, 1 for falls, 0 otherwise.
  )    e#   Increment. Gives 0 for rises, 2 for falls, 1 otherwise. Call this i.
  S3*  e#   Push a string with three spaces.
  0t   e#   Replace the i'th space (zero-based) with a zero.
}%
z      e# Transpose.
N*     e# Join with linefeeds.

6

Python 2, 76 71 байт

lambda s:[''.join(' o'[cmp(*x)==n]for x in zip(s,s[1:]))for n in-1,0,1]

Дякуємо @xnor за повідомлення про те, що дозволено повернення списку рядків.

Перевірте це на Ideone .


Вам дозволяється виводити список з трьох рядків, що дозволяє вам робити lambda.
xnor

Я є? Це все змінює.
Денніс

Я запитав у коментарях тому, що відповідь Лінни на Haskell це робила.
xnor

6

JavaScript (ES6), 96 95 89 87 82 байт

2 байти збережено за допомогою 0замість того o, як запропонував Conor O'Brien
2 6 байт збережено завдяки ETHproductions

let f =

s=>[1,0,-1].map(k=>s.replace(/./g,(c,i)=>i--?(c>s[i])-(c<s[i])-k&&' ':'')).join`
`

console.log(f("HELLOWORLD"));
console.log(f("EXAMINATION"));


1
Оскільки ви можете використовувати будь-який символ, чи заміняє 'o'на 0допомогу будь-який?
Conor O'Brien

@ ConorO'Brien - Дійсно, так і є. ;)
Арнольд

1
Думаю s=>[1,0,-1].map(k=>[...s].map(c=>(r=p?(c>p)-(c<p)-k&&' ':'',p=c,r),p=0).join``).join`\n` , спрацювало б, заощадивши 2 байти.
ETHproductions

Ви можете зберегти ще один байт, захоплюючи попередній символ кожен раз , замість того , щоб вручну відстежувати його: s=>[1,0,-1].map(k=>[...s].map((c,i)=>(p=s[i-1])?(c>p)-(c<p)-k&&' ':'').join``).join`\n` . s.replaceтакож заощадить кілька байтів [...s].map().join().
ETHproductions

4

Perl, 47 байт

Включає +1 для -p

Введіть дані про STDIN:

bumpy.pl <<< ABBCBA

bumpy.pl:

#!/usr/bin/perl -p
$_ x=3;s%.%/\G(.)(.)/?$2cmp$1^$.&&$":--$.>0%eg

4

MATL, 16 14 байт

dZSqq_tn:79Z?c

Спробуйте в Інтернеті!

Це випливало з обговорення відповіді DJMCMahem . Незважаючи на те, що ця відповідь на два символи більше однакової довжини, метод дещо відрізняється, тому він може становити незалежний інтерес.

Дякуємо Луїсу Мендо за пропозицію, економивши 2 байти (див. Коментарі)

Пояснення:

'dZS' отримує вектор, де кожен запис є знаком відмінностей між послідовними символами, тоді 'qq_' зменшує кожен запис на два і перевертає знак, тож якщо символ збільшується, він дорівнює 1, якщо він залишається тим самим 2, і якщо вона зменшується 3. Наприклад,

dZSqq_ applied to 'HELLOWORLD' creates the vector [3 1 2 1 1 3 1 3 3]

Далі, 't' робить копію попереднього вектора в стеку, потім 'n:' розміщує вектор [1,2,3,4, ...] також на стеку. Потім "79" розміщує значення 79 на стеку. Значення 79 вибирається тому, що це число для символу unicode 'o', яке ми отримаємо згодом. (Дякую Луїсу Мендо за ідею поставити значення 79 тут, а не пізніше)

tn:79 applied to [3 1 2 1 1 3 1 3 3] creates the following items:
[3 1 2 1 1 3 1 3 3]   <-- first item on the stack
[1 2 3 4 5 6 7 8 9]   <-- second item on the stack
79                    <-- third item on the stack

На даний момент у нас є точно індекси рядків, індекси стовпців і ненульове значення розрідженої матриці, яка має значення 79, куди ми хочемо вивести символ, і 0, куди ми хочемо виділити пробіл. Ми знімаємо ці три елементи зі стека і створюємо цю розріджену матрицю за допомогою команди "Z?" З розрідженою матрицею MATL. Це є,

dZSqq_tn:79 Z? applied to 'HELLOWORLD' outputs the following:
[0  79 0  79 79 0  79 0  0 ]
[0  0  79 0  0  0  0  0  0 ]   <-- 3-by-n sparse matrix
[79 0  0  0  0  79 0  79 79]

Залишилося лише перетворити матрицю з чисел на символи unicode, що робиться командою 'c'. 79-і стають 'o', а 0-і стають просторами:

dZSqq_tn:79Z?c applied to 'HELLOWORLD' outputs:
[  o   o o   o    ]
[    o            ]   <-- 3-by-n sparse matrix of characters.
[o         o   o o]

Потім отримана матриця символів неявно відображається.


Ви можете безпосередньо використовувати 79 як ненульове значення для розрідженої матриці, зберігаючи таким чином два байти. Крім того, я думаю, що це перший раз, коли рідкісні матриці використовуються у відповіді MATL :-)
Луїс Мендо

@LuisMendo Дякую! Я відредагував публікацію, щоб внести запропоновані вами зміни
Нік Алгер

3

PHP, 95 байт

for($b[1]=$b[0]=$b[-1]=" ";($s=$argv[1])[++$i];)$b[$s[$i-1]<=>$s[$i]][$i]=8;echo join("\n",$b);

1.Створіть масив рядків з альтернативою індексу -1 до 1 $b=array_fill(-1,3," ");

2.Заповніть рядки, залежні від оператора космічного корабля та положення входу

3.Вихід приєднайте до масиву новим рядком

Перший шлях 111 байт

for($o=" ";$i<$l=strlen($s=$argv[1])-1;)$o[$l*(1+($s[$i]<=>$s[$i+1]))+$i++]=8;echo join("\n",str_split($o,$l));

Використовуйте оператора <=> космічного корабля


1
Якщо ви кодуєте свою програму на латині-1 , це зручний ярлик для "\n". Ні, серйозно!
Лінн

1
Те саме " ", що може бути . Приклад. Під час перегляду ви хочете встановити кодування браузера на Latin-1.
Лінн

@Lynn або ~ ³ ~ † ~ '~' Дякую за ідею. Я віддаю перевагу unicode
Йорг Гюльсерманн,

2

JavaScript (ES6), 81 байт

s=>[s,s,s].map(f=([c,...s],n)=>(p=s[0])?((c<p)-(c>p)+n-1&&" ")+f(s,n):"").join`
`

Написано з нуля, хоча воно було сильно натхнене відповіддю @ Арнальда . Використовує рекурсію для обчислення вмісту кожного рядка.



2

Java 7, 158 156 байт

String c(char[]z){String a,b,c=a=b="";for(char i=1,q=z[0],o=79,s=32,x;i<z.length;a+=(x=z[i])>q?o:s,b+=x==q?o:s,c+=x<q?o:s,q=z[i++]);return a+"\n"+b+"\n"+c;}

2 байти збережено завдяки @Frozn .

Невикористані та тестові справи:

Спробуйте тут.

class M{
  static String c(char[] z){
    String a,
           b,
           c = a = b = "";
    for(char i = 1,
             q = z[0],
             o = 79,
             s = 32,
             x; i < z.length; a += (x = z[i]) > q
                                     ? o
                                     : s,
                              b += x == q
                                     ? o
                                     : s,
                              c += x < q
                                     ? o
                                     : s,
                              q = z[i++]);
    return a + "\n" + b + "\n" + c;
  }

  public static void main(String[] a){
    print("HELLOWORLD");
    print("TESTCASE");
    print("EXAMINATION");
    print("ZSILENTYOUTH");
    print("ABC");
    print("ABCBA");
    print("ABBCBA");
    print("UVVWVVUVVWVVUVVW");
  }

  static void print(String s){
    System.out.println(c(s.toCharArray()));
    System.out.println("-------------------------");
  }
}

Вихід:

 O OO O  
  O      
O    O OO
-------------------------
 OO  O 

O  OO O
-------------------------
O O O O O 

 O O O O O
-------------------------
  O OOO O  

OO O   O OO
-------------------------
OO


-------------------------
OO  

  OO
-------------------------
O O  
 O   
   OO
-------------------------
O O   O O   O O
 O  O  O  O  O 
   O O   O O   
-------------------------

1
Я не впевнений, чи працює це, але a,b,c=b=a=""було б коротше.
Frozn

@Frozn Спасибі, відредаговано. Це справді працює. PS: ти міг би перевірити себе в ідеоні, піднявши його. ;)
Кевін Круїссен

Ти правий! Я завжди переглядаю посилання і починаю затемнення саме для цього не варто :)
Frozn,

2

Клора (20 байт)

<IN?o ;=IN?o ;>IN?o

Пояснення:

Існує 3 програми Clora, по одній для кожного вихідного рядка.

Перша програма, <IN?o

Перевірте, чи поточний показник входу Iменший <за наступний N. Збережіть результат у глобальному прапорі. Перевірте результат прапорця, ?і якщо це правда, виведіть o, інакше порожній пробіл (так, там є порожній пробіл.

Усі інші програми, дотримуючись того самого правила, розділені між собою ;, кожна програма виконується і отримує вхід як аргумент.

Ви можете перевірити його самостійно, включаючи clora.js та виконати його

(function() {
  var x = new Clora('<IN?o ;=IN?o ;>IN?o ');
  x.execute('EXAMINATION', function(r) {
    console.log(r)
  })
})();

Це здається суворо неконкуренним, оскільки воно було створене після цього виклику. Це схоже на цікавий язик!
Conor O'Brien

1

Pyth, 21 байт

jCmX*3\ h._d0-M.:CMz2

Програма, яка приймає введення без котировки рядка на STDIN і друкує результат.

Це використовує подібну ідею @ MartinEnder в CJam відповідь .

Спробуйте в Інтернеті або Перевірте всі тестові випадки .

Як це працює

jCmX*3\ h._d0-M.:CMz2  Program. Input: z
                 CMz   Map ordinal over z, yielding the code-points of the characters
               .:   2  Yield all length-2 sublists of that
             -M        Map subtraction over that
  m                    Map the following over that with variable d:
         ._d            Yield the sign of d
        h               Increment that (i)
    *3\                 Yield string literal of 3 spaces, "   "
   X        0           Replace the space at index i with 0
 C                     Transpose that
j                      Join that on newlines
                       Implicitly print

1

PHP 7, 81 80 77 байт

Примітка: використовується кодування Windows-1252

for($x=2;~$x--;print~õ)for($a=$argn;$c=$a[$$x+1];)echo$c<=>$a[$$x++]^$x?~ß:o;

Бігайте так:

echo HELLOWORLD | php -nR 'for($x=2;~$x--;print"\n")for($a=$argn;$c=$a[$$x+1];)echo$c<=>$a[$$x++]^$x?" ":o;';echo

Пояснення

Ітерація через лінію (пронумеровано 1, 0, -1). Потім повторюється вхідний рядок для кожного рядка. Коли результат порівняння космічного корабля дорівнює номеру рядка, виведіть а o, в іншому випадку, виведіть пробіл. Після кожного рядка надрукуйте новий рядок.

Налаштування

  • Зупиніть ітерацію, коли $xє -1, що ми можемо знайти за допомогою бінарного заперечення (результату 0). Зберігає байт порівняно з додаванням 1(або 2 з попереднім збільшенням).
  • Збережено 3 байти за допомогою $argn

1
Ви забули додати -d error_reporting=30709до своєї кількості байтів.
Тит

@Titus Чому в світі мені потрібно додати це до числа байтів? Це лише так, що повідомлення про PHP (які є невідомими) не друкуються!
aross

Можна також додати 2>/dev/null, але це позбудеться ВСІХ помилок, включаючи фатальні
1616


Щось подібне If you get warnings, set the default value with .... Вибачте, будь ласка, про мою педантичність; Я не розшифрував це значення.
Тит

0

Луа 326 303 байт tl = 0 s = io.read () o1, o2, o3 = "", "", "" t = {} для i = 1, # s do t [i] = s: sub (i , i) tl = tl + 1 кінець для v = 1, tl-1 зробимо, якщо t [v] t [v + 1], то o1 = o1 .. "" o2 = o2 .. "" o3 = o3 .. " o "кінцевий друк (o1 .." \ n ".. o2 .." \ n ".. o3)

Негольована версія

tl = 0 --set the tables length to 0
s = io.read() --Get the string from input
o1,o2,o3="","","" --Set the 3 output rows to empty strings
t = {} --Make a table for the string to be sent into
for i = 1, #s do --Loop from 1 to the length of the string
    t[i] = s:sub(i, i) --Set the I-th term in the table to the I-th character in the string
    tl = tl+1 --Add 1 to the table length
end --End the loop
for v=1,tl-1, 1 do --Loop from 1 to the tables length - 1, incrementing by 1
    if t[v] < t[v+1] then --Lua supports greater than less than and equals to with charactes, so this if statement detects if the string is rising
        o1=o1.."o" --Adds an o to the end of the first line of output
        o2=o2.." " --Adds a space to the second line
        o3=o3.." " --Adds a space to the third line
    elseif t[v] == t[v+1] then --Detects if the string is continuing
        o1=o1.." " --Adds a space to the first line
        o2=o2.."o" --Adds an o to the second line
        o3=o3.." " --Adds a space to the third line
    elseif t[v] > t[v+1] then --Detects if string is falling
        o1=o1.." " --Adds a space to the first line
        o2=o2.." " --Adds a space to the second line
        o3=o3.."o" --Adds an o to the third line
    end --Ends the if statement
end --Ends the loop
print(o1.."\n"..o2.."\n"..o3) --Prints the output

Я думаю, ти можеш відігнати пробіл із, скажімо t1 = 0,? до t1=0? І подібні місця.
Conor O'Brien

Я зараз це
Алекс Аллен

0

R, 114 байт

Неконкурентна відповідь R.

v=y=z=rep(" ",length(x<-diff(utf8ToInt(scan(,"")))));v[x>0]="#";y[x==0]="#";z[x<0]="#";cat(v,"\n",y,"\n",z,sep="")

Пояснення

  1. Прочитайте введення з командного рядка та перетворіть у десятковий вектор ascii
  2. Візьміть першу різницю і створіть 3х вектори однакової довжини з пробілами
  3. Потім замініть білі простори вектора на, #якщо відмінності є >0, ==0або <0.
  4. Примушуйте вектори і друкуйте їх розділеними новими рядками

Чому неконкуренто?
Conor O'Brien

@ ConorO'Brien Я думаю, що він конкурує з іншими відповідями на R, але оригінальне рішення було способом довгим і не унікальним, щоб бути цікавим у загальному сенсі.
Billywob
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.