Обратный текст бустрофедона

19

Бустрофедон - это тип двунаправленного текста, в котором чередующиеся строки чередуются между чтением слева направо и справа налево. Направление символов также было отражено относительно направления чтения. В системах с обратным написанием бустрофедонов персонажи поворачивались на 180, а не отражались.

Вызов

Напишите программу / функцию, которая принимает строку текста и количество столбцов и выводит строку, отформатированную в указанное количество столбцов, при этом чередующиеся строки переворачиваются вверх ногами.

вход

Ваша программа должна принимать два аргумента:

  • S, строка текста для форматирования
  • N, количество столбцов

Выход

Ваша программа должна вывести S, завернутый в N столбцов с чередующимися перевернутыми линиями на 180 градусов.

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

Вот символы, которые ваша программа должна поддерживать со своими перевернутыми аналогами:

Uppercase:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
∀qƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMX⅄Z

Lowercase:
abcdefghijklmnopqrstuvwxyz
ɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz

Punctuation:
&_?!"'.,
⅋‾¿¡„,˙'

Тестовые случаи

S: The quick brown fox jumps over the lazy dog.
N: 30
Output:
The quick brown fox jumps over
                ˙ƃop ʎzɐl ǝɥʇ 

S: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vel libero arcu. Nunc dictum elementum lectus nec aliquet. Donec dolor nunc, sodales at dolor rhoncus, hendrerit scelerisque purus. Pellentesque vel sagittis libero, et rutrum leo. Nullam vulputate enim et massa dictum, vitae venenatis augue lobortis. Fusce sollicitudin ultrices consequat. Vestibulum quis nunc non tortor eleifend facilisis. In at nunc elit. Aliquam pellentesque, lectus quis aliquam posuere, quam lectus sagittis metus, ut auctor sem quam a neque. Integer rhoncus lobortis nisl. Pellentesque mi dui, laoreet in metus quis, mollis accumsan est. Nunc dignissim tortor ac eleifend tempus. Ut ut tellus aliquam, luctus nulla quis, consectetur nunc. Suspendisse viverra molestie condimentum. Curabitur et hendrerit augue.
N: 50
Output:
Lorem ipsum dolor sit amet, consectetur adipiscing
uǝɯǝlǝ ɯnʇɔᴉp ɔunN ˙nɔɹɐ oɹǝqᴉl lǝʌ ǝnbsᴉnQ ˙ʇᴉlǝ 
tum lectus nec aliquet. Donec dolor nunc, sodales 
lǝԀ ˙snɹnd ǝnbsᴉɹǝlǝɔs ʇᴉɹǝɹpuǝɥ 'snɔuoɥɹ ɹolop ʇɐ
lentesque vel sagittis libero, et rutrum leo. Null
sᴉʇɐuǝuǝʌ ǝɐʇᴉʌ 'ɯnʇɔᴉp ɐssɐɯ ʇǝ ɯᴉuǝ ǝʇɐʇndlnʌ ɯɐ
 augue lobortis. Fusce sollicitudin ultrices conse
ɔɐɟ puǝɟᴉǝlǝ ɹoʇɹoʇ uou ɔunu sᴉnb ɯnlnqᴉʇsǝΛ ˙ʇɐnb
ilisis. In at nunc elit. Aliquam pellentesque, lec
ʇǝɯ sᴉʇʇᴉƃɐs snʇɔǝl ɯɐnb 'ǝɹǝnsod ɯɐnbᴉlɐ sᴉnb snʇ
us, ut auctor sem quam a neque. Integer rhoncus lo
snʇǝɯ uᴉ ʇǝǝɹoɐl 'ᴉnp ᴉɯ ǝnbsǝʇuǝllǝԀ ˙lsᴉu sᴉʇɹoq
 quis, mollis accumsan est. Nunc dignissim tortor 
u snʇɔnl 'ɯɐnbᴉlɐ snllǝʇ ʇn ʇ∩ ˙sndɯǝʇ puǝɟᴉǝlǝ ɔɐ
ulla quis, consectetur nunc. Suspendisse viverra m
˙ǝnƃnɐ ʇᴉɹǝɹpuǝɥ ʇǝ ɹnʇᴉqɐɹnƆ ˙ɯnʇuǝɯᴉpuoɔ ǝᴉʇsǝlo
Dendrobium
источник

Ответы:

5

Утилиты Bash + GNU, 204

fold -$1|sed 2~2{s/.\\+/printf\ %$1's "`echo "&"|rev`"/e
y/'`printf %s {A..Z} {a..z}`"&_?!\"'.,/∀qƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMX⅄Zɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz⅋‾¿¡„,˙'/
}"

N задается в командной строке, а S - через STDIN:

$ echo "The quick brown fox jumps over the lazy dog." | ./boustrophedon.sh 30
The quick brown fox jumps over
                ˙ƃop ʎzɐl ǝɥʇ 
$ 

объяснение

  • fold -N разбивает ввод на строки длиной N.
  • Остальная часть обработки выполняется sed, строка за строкой:
    • 2~2 соответствует любой другой строке, начиная со строки 2
    • s/.+/printf %'N's "`echo "&"|rev`"/e использует функцию exec GNU Sed для вызова оболочки, чтобы перевернуть строку и дополнить ее левой клавишей до N пробелов
    • y/ABC.../∀qƆ.../ трансформировать персонажей

Примечание ABC...генерируется с использованием расширения bash и printf. Также некоторые модные цитаты для всех разных персонажей.

Цифровая травма
источник
Спасибо @isaacg - я думал, что пробовал двойной бэкстик, но, наверное, я пропустил это.
Цифровая травма
3

Japt , 182 179 байт

Japt - это сокращенная версия Ja vaScri pt . переводчик

Ur'.+".?"pV-1 ,@A++%2?SpV-Xl)+Xw m@"„\xA1⅋,'˙¿∀qƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMX⅄Z[\\]^‾`ɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz"g(Q+"!&',.?"+65o124 m@Xd)a)bX)||X +R:X+R

Как это устроено

             // Implicit: U = input string, V = input number, A = 10
Ur           // Take U and replace each group X of:
'.+".?"pV-1  //  at least one char, followed by up to V-1 other chars
             //   literally: RegExp("." + ".?".repeat(V-1))
@            // with: (@ is compiled to (X,Y,Z)=>)
A++%2?       //  If we're on an odd row:
SpV-Xl)+     //   Pad it with spaces, then concatenate it with
Xw m@        //   X reversed, with each character X mapped to:
"..."g       //   The character at position N in the string, where N is:
(Q+"!&',.?"  //    Build a string from a quote mark and these chars,
65o124 m@Xd)a) //   and all chars from A..z.
bX)          //    Return the index of X in this string.
||X          //   or if this number is outside the string, default to the original char.
+R           //   Either way, add a newline.
:X+R         //  Otherwise, return the original row text plus a newline.
             // Implicit: output last expression

Есть несколько проблем, но они не должны влиять на действительность программы:

  1. Пользователь @ Vɪʜᴀɴ недавно помог мне внедрить Unicode Shortcuts или отдельные символы в диапазоне 00A1-00FF, которые заменяют часто используемые последовательности из нескольких символов. Проблема заключается в том, что он в настоящее время заменяет внутренние строки, поэтому мы не можем сейчас использовать непосредственно в строке. Безопасная альтернатива, на \xA1три байта длиннее.
  2. В настоящее время невозможно ввести символ двойной кавычки. Это будет исправлено в ближайшее время.

Возможно, есть способ сократить строку. Предложения приветствуются!

ETHproductions
источник
Ницца! Я хотел попытаться преобразовать свое решение в Japt позже, но это берет пирог.
Скотт
2

CJam, 152

l~_q/\f{Se]}2/{)26,'Af+_el+"&_?!'.,"`+"∀qƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMX⅄Zɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz„⅋‾¿¡,˙'"erW%}%N*

Проверьте это здесь.

Думаю, мне стоит немного сжать эту строку Unicode ...

Мартин Эндер
источник
Сжатие этой строки в Юникоде сложно - кодовые точки повсюду. В качестве эксперимента я попытался «сделать zopfli» всю мою запись (включая биты sed) и в итоге стал больше. Я буду с интересом наблюдать, как ты справишься с этим :)
Digital Trauma
2

Javascript (ES6), 407 400 366 360 353 байта

Я считаю только первые две «строки» в этом фрагменте как общее количество, так как остальная часть - это код для его запуска.

s=`ABCDEFGHIJKLMNOPQRSTUVWXYZqƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMXZabcdefghijklmnopqrstuvwxyzɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz&_?!"'.,⅋‾¿¡„,˙'`,f=(i,w)=>(i=i.match(RegExp(`.{1,${w}}`,"g")),i.map((c,x)=>x%2?" ".repeat(w-c.length)+[...c].reverse().map(b=>(d=s.indexOf(b),"A"<=b&&"z">=b?s[d+26]:" "==b?b:s[d+8])).join``:c).join`
`)

let input = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque vel libero arcu. Nunc dictum elementum lectus nec aliquet. Donec dolor nunc, sodales at dolor rhoncus, hendrerit scelerisque purus. Pellentesque vel sagittis libero, et rutrum leo. Nullam vulputate enim et massa dictum, vitae venenatis augue lobortis. Fusce sollicitudin ultrices consequat. Vestibulum quis nunc non tortor eleifend facilisis. In at nunc elit. Aliquam pellentesque, lectus quis aliquam posuere, quam lectus sagittis metus, ut auctor sem quam a neque. Integer rhoncus lobortis nisl. Pellentesque mi dui, laoreet in metus quis, mollis accumsan est. Nunc dignissim tortor ac eleifend tempus. Ut ut tellus aliquam, luctus nulla quis, consectetur nunc. Suspendisse viverra molestie condimentum. Curabitur et hendrerit augue.";
console.log(f(input, 50));

объяснение

s=`A∀ .. ZZaɐ .. &⅋ ..`,                            //Character translation "map"
f=(i,w)=>                                           //Create a function named "f" that takes an (i)nput string and (w)idth
    (                                               //Implicitly return
        i=i.match(RegExp(`.{1,${w}}`,"g")),         //Cut string into arrays every w-th match of anything
        i.map((c,x)=>                               //Loop through each element in array by (c)ut at inde(x)
            x%2                                     //If the index is odd
                ?" ".repeat(w-c.length)                 //Output spaces for padding
                    +[...c].reverse()                   //Split this cut into each character, and read it backwards
                    .map((b,d)=>(                       //Translate each character
                        d=s.indexOf(b),                 //Save where this character appears in the mapping
                        "A"<=b&&"z">=b                  //If the character is a-zA-Z
                        ?s[d+26]                            //Print the flipped character by looking 26 characters ahead of where this character is found
                        :" "==b                             //Else, if it's a space
                            ?b                              //Output the space
                            :s[d+8]))                   //Else, print the flipped punctuation character (only 8 of these)
                    .join``                         //Join everything back into a continuous string
                :c                                  //Else just output the whole cut
            ).join`                                 
`)                                                  //Finally join each cut by a newline

  • Спасибо Дендробиуму за -6 байт!
  • Спасибо Closure Compiler за -34 байта!
  • Спасибо ן nɟuɐɯɹɐ ן oɯ за -7 байтов!
Скотт
источник
1
Вы можете уменьшить все свои .split("")и .join("")до .split``и .join``сбрить несколько байтов. .join("\n")Также может быть переписано как выше с буквальным переводом строки вместо \n.
Дендробиум
Отличные советы, большое спасибо!
Скотт
1
Вы можете удалить новое ключевое слово для регулярного выражения. Также используйте exec вместо match. Ах да, используйте [... c] вместо c.split``.
Mama Fun Roll
@ ן nɟuɐɯɹɐ ן oɯ Хорошо, спасибо! Я не мог понять, как использовать execи держать его коротким, так как execнужно зациклить, чтобы получить все совпадения.
Скотт
О, не обращайте внимания на exec ...
Mama Fun Roll
1

Pyth, 141 байт

FNrZlKczQI%N2X.[" "Q_@KN++GrG1"&_?!\"'.,""ɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz∀qƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMX⅄Z⅋‾¿¡„,˙'")E@KN

Протестировано с онлайн-компилятором Pyth.

Как это устроено

FNrZlKczQI%N2X.[" "Q_@KN)E@KN    █
                                 █
FN                               █ For N in 
  r                              █  ├ Range
   Z                             █  |  ・Start: 0 
                                 █  |  ・End: 
    l                            █  |     Length of
     K                           █  |      └─K = 
      c                          █  |         Split
       z                         █  |           ・String z
        Q                        █  |           ・By input int Q
         I%N2                    █  └─If divisible by 2
             X                   █     └─Translate
                                 █         ├─Source:
              .[                 █         | ├─Pad left
                " "              █         | |   ・With spaces
                   Q             █         | |   ・Until input int Q
                    _            █         | └──Reverse
                     @KN         █         |     ・Nth line of K
                        ++GrG1...█         ├─From: Normal  (See below)
                        "ɐqɔpǝ...█         └─To:   Flipped (See below)
                        )E@KN    █     Else print Nth line of K

карта

Обычный

++                               █ Append:
  G                              █  1) a to z
   rG1                           █  2) A to Z
      "&_?!\"'.,"                █  3) Punctuation

Перевернуто (Ничего особенного)

"ɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz∀qƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMX⅄Z⅋‾¿¡„,˙'"
Helix Quar
источник
Это 108 символов в длину; однако способ измерения длины программ для игры в гольф по умолчанию - байты . Согласно этой странице длина этого ответа составляет 141 байт .
ETHproductions
@ETHproductions Спасибо. Изменено.
Helix Quar
0

Python, 453 363 байта

s,n=input()
o="""ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&_?!"'.,"""
p="""∀qƆpƎℲפHIſʞ˥WNOԀQɹS┴∩ΛMX⅄Zɐqɔpǝɟƃɥᴉɾʞlɯuodbɹsʇnʌʍxʎz⅋‾¿¡„,˙'""".decode('utf8')
s=map(''.join,zip(*[iter(s+' '*(n-1))]*n))
for i in range(len(s)):
 if i%2:s[i]=''.join(p[o.find(c)].encode('utf8')for c in s[i][::-1])
for l in s:print l
TFeld
источник