Нарисуйте неровную строку


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 Мин.

@JHM Конечно, все в порядке.
Конор О'Брайен

Кроме того, вывод должен быть строкой, или он должен выглядеть только как в примере?
JungHwan Мин.

@JHM Что ты имеешь в виду?
Конор О'Брайен

Код, который я имею в виду, генерирует сетку.
JungHwan Мин.

Ответы:


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

Mathematica, 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 байт?
Конор О'Брайен,

@ ConorO'Brien, пожалуйста, смотрите редактирование.
JungHwan Мин.

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<-[(<),(==),(>)]]

Возвращает список из трех строк, представляющих строки вывода. Не содержит подсознательных сообщений.

Дайанна сохранила три байта, используя doнотацию и maxвместо понимания списка и last.


3
Отлично, в нем нет подсознательных сообщений! Что это?
Конор О'Брайен,

5
['o'|b e y]..
Изабера

Да, мой мастер Подожди, что происходит?
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, как предложено Конором О'Брайеном
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помощью любой?
Конор О'Брайен,

@ 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 байта.
ETHпродукция

Вы можете сохранить еще один байт, захватывая предыдущий символ каждый раз , вместо того , чтобы вручную отслеживать его: 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 символа длиннее одинаковой длины, метод несколько отличается, поэтому он может представлять самостоятельный интерес.

Спасибо Луису Мендо за предложение сэкономить 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 выбрано потому, что это номер для символа юникода '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, где мы хотим вывести пробел. Мы убираем эти три элемента из стека и создаем эту разреженную матрицу с помощью команды разреженной матрицы MATL 'Z?'. То есть,

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]

Осталось только преобразовать матрицу из чисел в символы Юникода, что делается командой '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 при просмотре.
Линн

@ Линн или ~ ³ ~ † ~ '~' Спасибо за идею. Я предпочитаю 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`
`

Написанный с нуля, хотя он был сильно вдохновлен ответом @ Arnauld . Использует рекурсию для вычисления содержимого каждой строки.



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 .

Ungolfed и тестовые случаи:

Попробуй это здесь.

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: вы могли бы проверить себя в ideone, разветвив его. ;)
Кевин Круйссен

Вы правы! Я всегда пропускаю ссылки и
запускаю

2

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

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

Объяснение:

Есть 3 программы Clora, по одной на каждую выходную строку.

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

Проверьте, Iменьше ли текущий входной символ, <чем следующий символ N. Сохраните результат в глобальном флаге. Проверьте результат флага ?и, если true, выведите o, в противном случае - пробел (да, там есть пробел.

Все остальные программы следуют тому же правилу и разделены ;, каждая программа выполняется и получает входные данные в качестве аргумента.

Вы можете проверить это самостоятельно, включая clora.js и запустив его

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

Это кажется абсолютно неконкурентным, так как он был создан после этой проблемы. Это выглядит как интересный язык, хотя!
Конор О'Брайен

1

Pyth, 21 байт

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

Программа, которая принимает ввод строки без кавычек в STDIN и печатает результат.

Это использует идею, аналогичную ответу CJam @ MartinEnder .

Попробуйте онлайн или проверьте все контрольные примеры .

Как это работает

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, в противном случае выведите пробел. После каждой строки выведите новую строку.

Tweaks

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

1
Вы забыли добавить -d error_reporting=30709к вашему счету байтов.
Тит

@ Titus Почему в мире мне нужно добавить это к числу байтов? Это только для того, чтобы PHP-уведомления (которые игнорируются) не печатались!
aross

Можно также добавить 2>/dev/null, но это будет избавиться от всех ошибок, в том числе со смертельным исходом
aross


Нечто подобное If you get warnings, set the default value with .... Пожалуйста, извините мою педантизм; Я не расшифровал это значение.
Тит

0

Lua 326 303 байта tl = 0 s = io.read () o1, o2, o3 = "", "", "" t = {} для i = 1, # s делают 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 "end end print (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? И подобные места.
Конор О'Брайен

Я исправлю это сейчас
Алекс Аллен

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. Возьмите 1-ую разницу и создайте 3x вектора одинаковой длины с пробелами
  3. Затем замените векторы пробелов на, #если различия есть >0, ==0или <0.
  4. Приведите векторы и выведите их через пробел.

Почему неконкурентоспособен?
Конор О'Брайен,

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