Простой способ кодирования гольфа в ascii art!


18

Задача:

На этом сайте есть много ответов, которые организованы в ascii art, как этот . Обычно это делается вручную, но не поможет ли программа в этом? :)

Ваша программа будет принимать 3 входа:

  • Код, как одна строка
  • Количество строк в шаблоне (может быть опущено, если не нужно)
  • Сам шаблон, как *s или другой символ

Правила:

  • Вы должны написать программу (не функцию), которая читает из стандартного ввода
  • Текст размещается слева направо в каждой строке
  • Если текста недостаточно для заполнения шаблона, поставьте .s в оставшиеся пробелы
  • Если текста слишком много для заполнения шаблона, распечатайте его после вывода
  • , поэтому выигрывает самый короткий код в байтах

Пробные прогоны:

Вход (тест точной посадки) :

qwertyuiopasdfghjklzxcvbnm
4
***** * ***
*   * * *
*   * * *
***** * ***

Выход :

qwert y uio
p   a s d
f   g h j
klzxc v bnm

Ввод (тест дополнительных символов) :

qwertyuiopasdfghjklzxcvbnm12345
4
***** * ***
*   * * *
*   * * *
***** * ***

Выход :

qwert y uio
p   a s d
f   g h j
klzxc v bnm
12345

Ввод (тест на недостаточность символов) :

qwertyuiopasdfg
4
***** * ***
*   * * *
*   * * *
***** * ***

Выход :

qwert y uio
p   a s d
f   g . .
..... . ...

2
Какие предположения следует сделать относительно того, где допустимо вставлять пробелы и символы новой строки, не изменяя семантику программы?
Питер Тейлор

1
@PeterTaylor кажется, что нет никакой возможности для размещения / разделения кода, так что я полагаю, что семантика игнорируется?
Мартин Эндер

1
То, что части спецификации «можно опустить» и «или другой символ» означает, что мы можем, скажем, указать, что число строк должно быть пропущено и что звездочки должны быть заменены, скажем, Xна наши программа для работы?
Илмари Каронен

1
@Bakuriu Я не понимаю твой комментарий. Если вы пишете программу в ASCII, то каждый символ является байтом. Если вы пишете в UTF-32, то каждый символ составляет 4 байта. Самый короткий код в байтах , а не в символах, выигрывает в соответствии с текущей спецификацией. Похоже, вы хотите, чтобы кодирование стало требованием, но я не понимаю, почему это необходимо. Я неправильно понял ваш комментарий?
Рейнболт

1
Основываясь на некоторых ответах, пропущенных по некоторым правилам, я добавил два примера и переместил весь блок примеров под блоком правил для большей ясности.
Веска

Ответы:


5

GolfScript, 30 символов

n/(\(;n*'*'/{@.!'.'*+([]+@+}*\

Запустить онлайн .

Примеры:

> qwertyuiopasdfghjklzxcvbnm
> 4
> ***** * ***
> *   * * *
> *   * * *
> ***** * ***

qwert y uio
p   a s d
f   g h j
klzxc v bnm

> qwertyuiopasdfghjklzxcvbnm
> 1
> ***** * ***

qwert y uio
pasdfghjklzxcvbnm

> qwerty
> 2
> ***** * ***
> *   * * *

qwert y ...
.   . . .

10

Perl 6: 60 символов РЕДАКТИРОВАТЬ : 38 баллов (см. Внизу)

  #C#O     D#E#G#O       #L#
#F    #.#S#       T#A#C#K
  get\     .subst(       "*"
,{    shift       BEGIN [
  get\     .comb,\       "."
xx    * ]},       :g)\ .\
  say\     xx get\       ()\
#E    #X#C#       H#A#N#G
  #E#.     #C#O#M#       #!#

Если вы не цените мои ужасные художественные навыки, вот гольф:

get.subst("*",{shift BEGIN [get.comb,"."xx*]},:g).say xx get

Этот делает странные вещи со временем оценки.

Во-первых, BEGINключевое слово вынуждает [get.comb, "." xx *]вычисляться первым, помещая в массив список символов, составляющих «код», за которым следует бесконечное количество "."s.

Затем, getв конце оценивается, получая количество строк художественного шаблона ASCII. xxОператор повторяет первую часть программы это много раз. Это имеет больше смысла, когда вы понимаете, что code() xx count()это в основном сахар для code() for 1..count(): count()следует оценить в первую очередь.

Наконец, getв начале программы получает строку художественного шаблона ASCII и заменяет каждый "*"значением, смещенным относительно начала массива, который мы создали до всего остального ( {shift BEGIN …}).

РЕДАКТИРОВАТЬ:

Гольф до 37 символов, плюс один для переключателя командной строки:

perl6 -pe's:g[\*]=shift BEGIN [get.comb,"."xx*]'

Это та же концепция, что и в оригинале: -pпереключатель выполняет итерацию по каждой строке (после того, как BEGINон прочитал в «коде») и заменяет все *s следующей буквой из «кода» перед его печатью. Формат ввода для этого не должен включать количество строк формата.


6

Ruby 2.0, 53 52 персонажа

c=gets.chop
$><<gets($n).gsub(?*){c.slice!(0)||?.}+c

Согласно спецификации, не использует параметр «количество линий».

Пример выполнения:

qwertyuiopasd
***** * ***
*   * * *
*   * * *
***** * ***

Выход:

qwert y uio
p   a s d
.   . . .
..... . ...

1
./ascii.rb: line 2: syntax error near unexpected token `(' ./ascii.rb: line 2: `puts gets($n).gsub(?*){c.slice!(0)||?.},c'
Не то чтобы Чарльз

@ Чарльз Я не могу получить эту ошибку в любой версии Ruby, которую я установил. Вот код, работающий на IDEONE: ideone.com/3HG3Fb
Пол Престиж

странно. IDEONE работал нормально. Во всяком случае, вы можете сохранить символ (пробел), заменив puts с $><<и меняя ,в конце концов к+
Не то,

@ Чарльз Хороший звонок. Благодарность!
Пол Престиж

2

PowerShell , 63 86 83 82 байта

+20 байт, спасибо @Veskah

param($s,$p)-join($p|% *ht($s|% Le*)'*'|% t*y|%{if($_-eq42){$_=$s[$i++]}"$_."[0]})

Попробуйте онлайн!

Менее гольф:

param($string,$pattern)

$chars = $pattern |
    % PadRight ($string|% Length) '*' |
    % toCharArray |
    % {
        if($_-eq42){$_=$string[$i++]}    # $_ can become $null
        "$_."[0]                         # $_ or '.' if $_ is $null
    }
-join($chars)


2

T-SQL, 142 байта

@h - вводимый текст

@ это шаблон

DECLARE @h varchar(max)='qwertyuiopasdfg'
DECLARE @ varchar(max)='
***** * ***
*   * * *
*   * * *
***** * ***'

WHILE @ like'%*'SELECT @=left(@,charindex('*',@)-1)+left(@h+'.',1)+stuff(@,1,charindex('*',@),''),@h=substring(@h,2,999)PRINT
concat(@,'
'+@h)

Попробуйте онлайн



1

JavaScript - 199

text="qwertyuiopasdfghjklzxcvbnm";
pattern="***** * ***\n*   * * *\n*   * * *\n***** * ***";

function p(a,c){z=c.length,y=a.length,x=0;for(i=z;i-->0;)if(c[i]=="*")x+=1;if(x-y>0)for(i=x-y;i-->0;)a+=".";for(;i++<x;)c=c.replace(new RegExp("[*]"),a[i]);console.log(c);console.log(a.substring(x))}

p(text,pattern);

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

РЕДАКТИРОВАТЬ: изменены, чтобы быть функцией, принимающей текст и шаблон


4
Хорошо ... но здесь используется жестко запрограммированный ввод.
Доктор

Я не был уверен, как справиться со стандартным вводом из JS, особенно с переводом строки. Предложения?
Мэтт

@Matt Node? Spidermonkey?
Не то чтобы Чарльз

Возможно, сделав это функцией ...
TheDoctor

4
136:function p(a,c){x=c.split(s='*').length-1;for(i=x-a.length;i--;)a+='.';for(;i++<x;)c=c.replace(s,a[i]);console.log(c+'\n'+a.substring(x))}
Майкл М.

1

JavaScript (ES6) - 96 87

r=(c,p)=>{c=0+c;console.log(p.replace(/\*/g,t=>(c=c.substr(1),c[0]||'.'))+c.substr(1))}

Примечание: как предложено ФП , я использую функцию. Но если требуется наличие программы, вот решение на 93 символа .

c=0+(x=prompt)();p=x();console.log(p.replace(/\*/g,t=>(c=c.substr(1),c[0]||'.'))+c.substr(1))

РЕДАКТИРОВАТЬ 1: Основные изменения, я не знаю, почему я не осознал это в первый раз: P Сохранено 40 символов.


Использование :

// r(code, pattern)
r("qwertyuiopasdfghjklzxcvbnm", "***** * ***\n*   * * *\n*   * * *\n***** * ***\n** ** **)

Тестовый ввод : (без ненужного необязательного номера согласно спецификации)

qwertyuiopasdfghjklzxcvbnm
***** * ***
*   * * *
*   * * *
***** * ***
** ** **

Выход :

qwert y uio
p   a s d
f   g h j
klzxc v bnm
.. .. ..      // not much text was there to fill *s - replaced with dots as per spec

Код Ungolfed :

function run(code, pattern){
  code = "0" + code;  // prepend a zero; useful for the substring operation ahead

  pattern = pattern.replace(/\*/g, function(){  // replace the dots
    // by removing the first letter of code
    // and replacing dot with the first-letter of leftover code 
    // and if it isn't there (code finished)
    // return a dot

    code = code.substr(1); 
    return c[0] || '.';
  });
  }

  // after this operation; code contains the last letter of the org. code

  console.log(  p +  // the pattern has now code
                "\n" +   // and a newline
                c.substr(1) // if there is more than one letter of code left; display it
             );
}

Было бы очень приятно услышать о любых предложениях от пользователей :)


1

Perl, 70 символов

@_=split'',<>=~s/\n//r;<>;print/\*/?shift@_||'.':$_ for map{split''}<>

Или без проверки границ, 56 символов

@_=split'',<>;<>;print/\*/?shift@_:$_ for map{split''}<>

Обратите внимание, что этот код не использует вторую строку, как в спецификации, и может быть сокращен на три символа <>;


1

Bash, 166 156 111 106

Читает со стандартного ввода, не берет счетчик строк. Первая строка ввода - это код, который вы хотите вставить в ascii art, все последующие строки - это ascii art, состоящий из @символа. Ввод имеет максимальную длину 999 символов и не может содержать косую черту . (Я решил не использовать *или #потому, что они имеют особое значение в Bash).

read -n999 -d/ i p
while [[ $p =~ @ && -n $i ]];do
p="${p/@/${i:0:1}}"
i=${i:1}
done
tr @ .<<<"$p"
echo $i

ВНИМАНИЕ: эта программа использует файл с именем p. После выполнения программы удалите p- она ​​запутает программу при втором запуске.

Большая часть работы здесь сделана

p="${p/@/${i:0:1}}"
i=${i:1}

Первая строка заменяет первую @в данной области первым символом кода. Вторая строка удаляет первый символ кода.

Если для заполнения фигуры не хватает кода, после основной операции ascii art выводится новая строка echo $i.


1

C, 98 , 91 символов

Здесь довольно простое C-решение длиной до 100 символов. Это не использует ввод количества строк. (В противном случае потребуется второй ненужный get ()).

char b[999],*s;c;main(){gets(s=b);while(~(c=getchar()))putchar(c^42?c:*s?*s++:46);puts(s);}

ungolfed:

char b[999],*s;c;
main(){
    gets(s=b);
    while(~(c=getchar()))
        putchar(c^42?c:*s?*s++:46);
    puts(s);
}

Вы можете использовать puts(s)вместо того, printf("%s",s)чтобы сохранить 7 байтов.
nyuszika7h

@ nyuszika7h Спасибо! Но я не знаю, \nявляется ли проблема дополнительной.
MarcDefiant

1

Python 2.7, 165 155 150 138 119 персонажей

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

import sys
r=raw_input
l=list(r())
w=sys.stdout.write
for c in"\n".join([r()for _ in[1]*input()]):w(c=='*'and(l and l.pop(0)or'.')or c)
w("".join(l))

Редактировать: новая функциональная версия 1.0.1 с еще меньшим количеством используемых байтов:

Edit2: map(r,['']*input()) вместо [r()for _ in[1]*input()]и удален неиспользованный импорт

Edit3: '>'*input() вместо ['']*input()сохранения одного символа и добавления символа подсказки для шаблона :)

r=raw_input
l=list(r())
print''.join(map(lambda c:c=='*'and(l and l.pop(0)or'.')or c,"\n".join(map(r,'>'*input())))+l)

Вы можете использовать (['.']+l).pop(0)вместо того, (len(l)and l.pop(0)or'.')чтобы сохранить 9 байтов. И input()вместо того, int(r())чтобы сохранить 1 байт.
nyuszika7h

Спасибо за input! К сожалению, ваш первый совет не работает, потому что он выводит точки при длине строки> 0.
Avall

Я понимаю, почему мое предложение не верно. Попробуйте (l+['.']).pop(0)вместо этого, но если это не сработает, вы все равно можете сохранить 4 байта, используя l andвместо len(l)and.
nyuszika7h

(l+['.']).pop(0)не удаляет элементы, lпоэтому печатается только первый символ, но lусловие работает :)
avall

1

C # (интерактивный компилятор Visual C #) , 122 байта

var n=ReadLine();int k=0;foreach(var z in In.ReadToEnd())Write(z>33?(n+new string('.',999))[k++]:z);Write(n.Substring(k));

Попробуйте онлайн!


Из-за нехватки подробностей и других ответов вы, вероятно, можете отказаться от "\n"+добавления дополнительных символов в одну строку
Веска

0

05AB1E , 18 17 15 байт

s0¢.$«0¹S.;0'.:

Принимает код как первый ввод, шаблон как второй (с 0вместо# ).

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

18 15 байтов альтернативы, принимая входные данные в обратном порядке:

0¢.$¹ì0IS.;0'.:

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

Объяснение:

s                # Swap with implicit inputs, so the stack order is now: [code, pattern]
 0¢              # Count the amount of "0" in the pattern
   .$            # Remove that many leading characters from the code
     «           # Append it to the (implicit) pattern input
      0¹S.;      # Replace every "0" one by one with the characters of the first code input
           0'.: '# Then replace any remaining "0" with "."
                 # (after which the result is output implicitly as result)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.