Распечатай американский флаг!

29

Специальный день независимости (США) - тематическая задача для вас сегодня. Вы должны написать программу, которая печатает это ascii-art представление американского флага.

0
|---------------------------------------------------------
| *   *   *   *   *   * #################################|
|   *   *   *   *   *                                    |
| *   *   *   *   *   *                                  |
|   *   *   *   *   *   #################################|
| *   *   *   *   *   *                                  |
|   *   *   *   *   *                                    |
| *   *   *   *   *   * #################################|
|   *   *   *   *   *                                    |
| *   *   *   *   *   *                                  |
|########################################################|
|                                                        |
|                                                        |
|########################################################|
|                                                        |
|                                                        |
|########################################################|
|                                                        |
|                                                        |
|########################################################|
|---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

Допускаются завершающие пробелы в каждой строке, а также один завершающий символ новой строки.

Обратите внимание, что это не совсем то, как должен выглядеть флаг, но это самое близкое, что я мог получить с ASCII.

Как обычно, это поэтому применяются стандартные лазейки и выигрывает самый короткий ответ в байтах!

DJMcMayhem
источник
Разрешен ли конечный пробел?
Деннис
@ Денис, пока это не чрезмерно, я не понимаю, почему нет. Так что один завершающий перевод строки в порядке.
DJMcMayhem
9
Я хотел бы сделать это поп-конкурс и посмотреть, кто печатает наиболее реалистичный флаг.
Hosch250
7
@ Hosch250 Это закончилось бы как "художественный конкурс"
Sp3000
1
@steveverrill Да, но мы могли бы нарисовать флаг на ветру, возможно.
Hosch250

Ответы:

21

CJam, 184 120 109 101 76 74 69 67 64 62 58 байт

0'-57*"  #"56f*'|f+7*2>" *  "50*22/W<Sf+..e&~J$]N'|+a37*.+

Попробуйте онлайн в интерпретаторе CJam .

идея

Самая интересная часть флага - рисунок звезд и полос.

Если мы повторим два пробела и знак числа 56 раз и добавим вертикальную черту к каждому, мы получим

                                                         |
                                                         |
#########################################################|

Повторяя эту схему 7 раз и отбрасывая первые две строки, мы получаем полосы:

#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|
                                                         |
                                                         |
#########################################################|

Теперь, если мы повторим строку " * "50 раз и разделим результат на куски длиной 22, мы получим звезды:

 *   *   *   *   *   *
   *   *   *   *   *  
 *   *   *   *   *   *
   *   *   *   *   *  
 *   *   *   *   *   *
   *   *   *   *   *  
 *   *   *   *   *   *
   *   *   *   *   *  
 *   *   *   *   *   *
   

Незначительные пробелы немного удалены, но мы можем это исправить, удалив последний кусок и добавив пробел к оставшимся.

Теперь, если мы накладываем полосы и звезды, мы получаем

 *   *   *   *   *   * #################################|
   *   *   *   *   *                                    |
 *   *   *   *   *   *                                  |
   *   *   *   *   *   #################################|
 *   *   *   *   *   *                                  |
   *   *   *   *   *                                    |
 *   *   *   *   *   * #################################|
   *   *   *   *   *                                    |
 *   *   *   *   *   *                                  |
########################################################|
                                                        |
                                                        |
########################################################|
                                                        |
                                                        |
########################################################|
                                                        |
                                                        |
########################################################|

Все, что осталось сделать, это добавить две строки по 57 штрихов, добавить столбец из 37 вертикальных полос и поместить вишню сверху.

Код

0         e# Push a zero.
'-57*     e# Push a string of 57 dashes.
"  #"56f* e# Repeat each character in the string 56 times.
'|f+      e# Append a vertical bar to each resulting string.
7*        e# Repeat the resulting array of strings 7 times.
2>        e# Discard the first two strings.
" *  "50* e# Repeat the string 50 times.
22/       e# Split the result into chunks of length 22.
W<        e# Discard the last, partial chunk.
Sf*       e# Append a space to each chunk.
..e&      e# Twofold vectorized logical AND.
          e# Since all characters in the strings are truthy, this always selects
          e# the second character, painting the stars over the stripes.
~         e# Dump all resulting strings on the stack.
J$        e# Copy the string of dashes.

]         e# Wrap the entire stack in an array.
N'|+a37*  e# Repeat ["\n|"] 37 times.
.+        e# Perform vectorized concatenation.
Деннис
источник
13
В течение очень короткого, волшебного момента я бил тебя
edc65
2
Не каждый день вы видите, как кто-то пишет программу CJam длиной в 120 байт.
lirtosiast
1
Что мне больше всего нравится, так это то, как вы нашли способ иметь 6 звезд на каждой линии, а затем избавиться от тех, которые вам не нужны.
Уровень Река St
@steveverrill: мне это тоже понравилось, но я нашел кое-что короче ...
Деннис,
Круто! (Вы сделали что-то подобное с сотами, не так ли?) Но теперь вам нужно пересмотреть наложенное изображение в вашем объяснении.
Уровень Река St
27

Python 2, 113 байт

for i in range(38):print i and"|"+["-"*57,(" *  "*7)[i%2*2:][:(i<11)*23].ljust(56,"  #"[i%3])+"|"][1<i<21]*(i<22)

Нарезка строк и проверка по модулю в изобилии.

Sp3000
источник
+1 Очень впечатляюще, на 7 байтов впереди моего рубинового ответа. И вы, и EDC65 опередили Денниса одновременно? Вот Это Да!
Уровень Река St
11
Ответ Python, который конкурирует с ответом CJAM. Какое время быть живым!
DJMcMayhem
3
Мне нравится, как само значение i=0печатается.
xnor
8

Brainf ** k, 3355 3113 1598 1178 782 байта

Что это за язык?

Вот оптимизированная для рук версия с 28 циклами. Я думаю, что дошел до этого.

Вот бег на ideone.com :

+++[>++++<-]>[>+++>+++>+++>++++++++++>+>++++<<<<<<-]>++++++>---->->>>.<--.
<++++.>>---.>+++++++[<........>-]<<.
<.<<<<+++++[>>.<.>..<<-]>>.<.>.<<++++[>>>........<<<-]>>>.>.>.
<.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
<.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
<.<<...<<+++++[>.>...<<-]++++[>>>........<<<-]>>>.>.>.
<.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
<.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
<.<<<<+++++[>>.<.>..<<-]>>.<.>.<<++++[>>>........<<<-]>>>.>.>.
<.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
<.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
>>>+++[<<<
<.>>>+++++++[<<<<........>>>>-]<<<.>.
>>++[<<
<.<<<<+++++++[>>........<<-]>>>>.>.
>>-]<<
>>>-]<<<
<.>>>+++++++[<<<<........>>>>-]<<<.>.
<.>>.>+++++++[<........>-]<<.
>>++++++++[<<<.>.<.>.>>-]

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

 1: +++[>++++<-]>[>+++>+++>+++>++++++++++>+>++++<<<<<<-]>++++++>---->->>>.<--.
 2: <++++.>>---.>+++++++[<........>-]<<.
 3: <.<<<<+++++[>>.<.>..<<-]>>.<.>.<<++++[>>>........<<<-]>>>.>.>.
 4: <.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
 5: <.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
 6: <.<<...<<+++++[>.>...<<-]++++[>>>........<<<-]>>>.>.>.
 7: <.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
 8: <.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
 9: <.<<<<+++++[>>.<.>..<<-]>>.<.>.<<++++[>>>........<<<-]>>>.>.>.
10: <.<<<<+++++[>>...<.<-]+++++[>>.......<<-]>>.>>.>.
11: <.<<<<++++++[>>.<.>..<<-]++++[>>........<<-]>>>>.>.
12: >>>+++[<<<
13: <.>>>+++++++[<<<<........>>>>-]<<<.>.
14: >>++[<<
15: <.<<<<+++++++[>>........<<-]>>>>.>.
16: >>-]<<
17: >>>-]<<<
18: <.>>>+++++++[<<<<........>>>>-]<<<.>.
19: <.>>.>+++++++[<........>-]<<.
20: >>++++++++[<<<.>.<.>.>>-]

Эта программа использует 10 ячеек памяти:

0: loop counter #1
1: loop counter #2
2: "*"  ASCII 42
3: spc  ASCII 32
4: "#"  ASCII 35
5: "|"  ASCII 124
6: "\n" ASCII 10
7: "0"  ASCII 48, "-"  ASCII 45
8: loop counter #3
9: loop counter #4

Линия 1

  • Эта строка устанавливает символы ASCII в регистрах со 2 по 7 (в основном). Некоторая настройка сделана позже.
  • Этот код сначала помещает 3 в регистр 0, а затем повторяет цикл 3 раза, увеличивая регистр 1 четыре раза каждый цикл: +++[>++++<-] . Тогда конечным результатом является то, что регистр 0 равен 0, а регистр 1 равен 12.
  • 12 используется в качестве счетчика цикла для следующего цикла. В течение 12 раз в цикле регистры 2, 3 и 4 увеличиваются в 3 раза, регистр 5 увеличивается в 10 раз, регистр 6 увеличивается в 1 раз, а регистр 7 увеличивается в 4 раза. В конце этого цикла они содержат: R2 (36), R3 (36), R4 (36), R5 (120), R6 (12), R7 (48). После того, как регистр цикла 2 увеличивается 6 раз, регистр 3 уменьшается в 4 раза, а регистр 4 уменьшается один раз. На данный момент значения: R2 (42), R3 (32), R4 (35), R5 (120), R6 (12), R7 (48). Все регистры, кроме 5 и 6, содержат свои начальные значения ASCII.
  • Следующий регистр 7 выводится "0"вверху флага!
  • Следующий регистр 6 уменьшается в два раза до 10 (новая строка ASCII) и выводится. Сделано с первой строчкой флага!

Линия 2

  • Сначала он увеличивает регистр 5 на 4, что делает его "|" (ASCII 124) и выводит его.
  • Затем он уменьшает регистр 7 на три, изменяя его с "0"(ASCII 48) на "-"(ASCII 45) и выводя его.
  • Затем он помещает 7 в счетчик циклов 3 (регистр 8) и зацикливается 7 раз, каждый раз выписывая по 8 штрихов, всего 7 * 8 = 56 штрихов.
  • Наконец это заканчивается выводом новой строки.

Линия 3

  • Эта строка содержит две петли.
  • Первый цикл пишет " * "5 раз.
  • Тогда " * "написано
  • Второй цикл зацикливается 4 раза, записывая 8, "#"всего 32.
  • Тогда "#", "|"и "\n"написано.

Строки 4 - 11

  • Эти строки используют ту же технику, что и строка 3, чтобы выписать звезды и полосы флага.

Линия 12

  • Эта строка запускает цикл, который запускается 3 раза.
  • Цикл заканчивается в строке 17.

Строка 13

  • Пишет полосу, которая проходит через флаг.
  • Использует цикл, который выполняется 7 раз, записывая "#"8 раз каждый раз через цикл.

Линия 14

  • Начало цикла, который запускается 2 раза.

Строка 15

  • Пишет полосу, которая проходит через флаг.
  • Использует цикл, который выполняется 7 раз, записывая " "8 раз каждый раз через цикл.

Строка 16

  • Конец внутреннего цикла, который начался в строке 14.

Строка 17

  • Конец внешнего цикла, который начался в строке 13.

Линия 18

  • Рисует нижнюю полосу флага.

Линия 19

  • Рисует нижнюю границу флага.

Линия 20

  • Рисует флагшток.
  • Зацикливание 8 раз, запись "|"и перевод строки дважды каждый раз через цикл.
vacawama
источник
2
Вам действительно удалось сжать флаг! Я надеюсь, что вы опубликуете объяснение, когда закончите играть в гольф. Я бы очень хотел знать, как это работает.
Деннис
Я опубликую объяснение. Я все еще играю в гольф!
Vacawama
7

/// : 225 символов

/D/ddd//d/--------//H/hhh//h/########//S/sss//s/        //A/aaaaa//a/ *  //b/|HHh|
|SSs|
|SSs|
//p/|
|
|
|
/0
|DDd-
|A * Hh#|
|  A Ss |
|A * Ss |
|  A Hh#|
|A * Ss |
|  A Ss |
|A * Hh#|
|  A Ss |
|A * Ss |
bbb|HHh|
|DDd-
pppp
manatwork
источник
7

JavaScript ( ES6 ), 153 156

Используя строку шаблона, есть 1 новая строка, которая является значимой и считается

Тестовый запуск фрагмента ниже (будь то EcmaScript 6, только Firefox)

// TEST - Just for testing purpose,redefine console.log

console.log = (...x) => O.innerHTML += x+'\n'

// SOLUTION

o=[0];for(o[r=1]=o[21]='-'[R='repeat'](57);++r<21;o[r]=" *  "[R](7).substr(r%2*2,r<11&&23)+'  #'[r%3][R](r<11?33:56)+'|')o[37]='';console.log(o.join`
|`)
<pre id=O></pre>

Чтобы быть еще более патриотичным, вот версия EcmaScript 5

// TEST - Just for testing purpose,redfine console.log

console.log = function(x){ O.innerHTML += x+'\n' }

// SOLUTION - 175 bytes

for(o=(A=Array)(38),o[0]=0,r=2;r<21;r++)o[r]=A(8)[J='join'](" *  ").substr((r&1)*2,r<11?23:0)+A(r<11?34:57)[J]('  #'[r%3])+'|';
o[1]=o[r]=A(58)[J]('-'),console.log(o[J]('\n|'))
<pre id=O></pre>

edc65
источник
4
+1 за вызов ES5 более патриотичным
Пит ТНТ
6

Рубин, 104 102 байта

Используя идеи из Ruby ManAtWork, отвечайте с разрешения.

puts 0,s=?|+?-*57,(0..18).map{|i|?|+("#  "[i%3]*(i>8?56:33)).rjust(56," *   *"[i%2*2,4])+?|},s,'|
'*16

Рубин, 127 121 112 байт

Изменены кавычки на ? используемый массив вместо условных для цвета полосы. вместо условной длины используется условная формула.

puts 0,s=?|+?-*57
19.times{|i|puts ?|+("#  "[i%3]*(i>8?56:33)).rjust(56,i%2>0?"   *":" *  ")+?|}
puts s,"|\n"*16

Хитрость здесь в том, чтобы нарисовать полосы (как красные, так #и белые space) до правильной длины, а затем выровнять их по правому краю, добавив звездочки. Ruby's rjustпозволяет нам указать строку дополнения, которая чередуется между" * " и " *".

Оригинальная версия, 127 байт

puts 0,s="|"+"-"*57
19.times{|i|puts("|"+((i%3>0?" ":"#")*((i+1)/10*23+33)).rjust(56,i%2>0?"   *":" *  ")+"|")}
puts s,"|\n"*16
Уровень реки St
источник
К сожалению, я забыл перезагрузить страницу, прежде чем проверять, существует ли уже ответ Ruby. Поскольку мой ответ существенно не отличается, я удалил его. Не стесняйтесь использовать любую хорошую часть, которую вы можете найти в ней.
manatwork
@manatwork Я не вижу, что вам нужно было удалить его, он был короче моего, и я уже проголосовал за него. Там были некоторые трюки с Ruby, которых я не знал, я новичок в ruby. Я опустился до 104, используя лучший из двух ответов, что является самым коротким ответом на обычном языке. Я не понимаю , почему я могу использовать mapв середине , puts но я не могу использовать его самостоятельно, даже если я его окружают со скобками: puts((0.18).map{}). Если вы заметите какие-либо дальнейшие улучшения, дайте мне знать или удалите свой собственный ответ и опубликуйте его там.
Уровень Река St
Я впечатлен тем, что Руби rjustможет взять строку, а не просто символ. Жаль, что Питон не может этого сделать ...
Sp3000
3

SWI-Пролог, 275 байт

На языке французского происхождения, который является своего рода подходящим

a:-put(48),nl,b,c(0).
b:-z,w(-,57).
c(I):-nl,I=36;J is I+1,(I=19,b,c(J);I>19,z,c(J);I>8,z,(I mod 3=:=0,w(#,56);tab(56)),z,c(J);z,(I mod 2=:=0,tab(1),w('*   ',5),put(42),tab(1);w('   *',5),tab(3)),(0=:=I mod 3,w(#,33);tab(33)),z,c(J)).
z:-put(124).
w(A,B):-writef('%r',[A,B]).

Смотрите результат здесь

Fatalize
источник
Ненавижу нарушать существующий ответ, но в первой версии было 11 полос вместо 13. Я больше ничего не менял. Вы можете проверить историю редактирования, чтобы увидеть, что я изменил. Прости за это.
DJMcMayhem
@DJMcMayhem Исправлено, нужно было только изменить два числа и не изменять длину ответа, так что все хорошо
Fatalize
1

С 235 211 208 205 203 198 197 186 байтов

i;x(){for(puts("0");i<37;i++){char b[58]="";i<21?memset(b,i%20?i%3&1?35:32:45,56),i&&i<10?memcpy(b," *   *   *   *   *   *   "+(i%2?0:2),23):0,b[56]=i%20?124:45:0;printf("|%.57s\n",b);}}

редактировать: добавил некоторые из предложений крутого парня и использовал?: заменить некоторые заявления if.

edit: устранено предотвращение переполнения \ 0 и используется ограничитель длины строки в printf.

edit: переработаны оба условия memset.

edit: перемещены ставит ("0") внутри заголовка для удаления его точки с запятой.

изменить: небольшой рефакторинг, чтобы получить еще 11 байтов.

openaddr
источник
Хорошая первая попытка. Но это, кажется, не печатать |в начале каждой строки ...
Spikatrix
Ваш код в 198 байт:i;c(){puts("0");for(;i<37;i++){char b[58]="|";if(i<21){memset(b,!((i-1)%3)?35:32,56);if(i<10)memcpy(b," * * * * * * "+((i%2)?0:2),23);b[56]='|';}if(!i||i==20){memset(b,45,57);}puts(b);}}
Spikatrix
@Cool Guy: Спасибо за улов. Я забыл переместить '|' вернуться ко второму printf из инициализатора. Я попытался запустить ваш код с помощью GCC под Cygwin, но форматирование выключено. Что-нибудь особенное, что мне нужно сделать, чтобы запустить его, или какие-либо флаги, необходимые во время компиляции?
openaddr
Никаких специальных флагов не требуется. Протестируйте это здесь Гольф больше, используя 45вместо '-'и 35вместо '#'и 32вместо' '
Spikatrix
@Cool Guy: Хорошее предложение по значениям кодировки символов. И хороший улов на я == 0 я упустил из виду. Я думаю, что ваш исходный код не работал из-за второго метода put (), но это было частично моей ошибкой, потому что, забыв изменить позицию «|» обратно, он выглядел так, как будто буфер содержал всю строку. Код в ссылке, которую вы указали с помощью printf в конце, теперь работает.
openaddr