Cara mudah untuk membuat kode ascii golf!


18

Tugas:

Ada banyak jawaban di situs ini yang disusun menjadi seni ascii, seperti ini . Biasanya pengaturan dilakukan secara manual, tetapi tidakkah program membantu dengan itu? :)

Program Anda akan mengambil 3 input:

  • Kode, sebagai satu baris
  • Jumlah garis dalam pola (dapat dihilangkan jika tidak perlu)
  • Pola itu sendiri, seperti *s atau karakter lain

Aturan:

  • Anda harus menulis program (bukan fungsi) yang membaca dari stdin
  • Teks ditempatkan kiri-ke-kanan per baris
  • Jika tidak ada cukup teks untuk mengisi pola, letakkan .s pada spasi yang tersisa
  • Jika ada terlalu banyak teks untuk diisi pola, cetak setelah output
  • , jadi kode terpendek, dalam byte menang

Contoh Berjalan:

Input (Uji Kelayakan Tepat) :

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

Keluaran :

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

Input (Tes karakter tambahan) :

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

Keluaran :

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

Input (Uji Karakter Tidak Cukup) :

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

Keluaran :

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

2
Asumsi apa yang harus dibuat tentang di mana dimungkinkan untuk memasukkan spasi dan baris baru tanpa mengubah semantik program?
Peter Taylor

1
@PeterTaylor sepertinya tidak ada jalan untuk menempatkan / memisahkan kode, jadi saya kira semantik diabaikan?
Martin Ender

1
Apakah bagian "dapat dihilangkan" dan "atau karakter lain" dari spec berarti bahwa kita bebas untuk, katakanlah, tentukan bahwa jumlah garis harus dihilangkan dan bahwa tanda bintang harus diganti oleh, katakanlah, Xes untuk kita program untuk bekerja?
Ilmari Karonen

1
@ Bakuriu Saya tidak mengerti komentar Anda. Jika Anda menulis program di ASCII, maka setiap karakter adalah byte. Jika Anda menulis dalam UTF-32, maka setiap karakter adalah 4 byte. Kode terpendek dalam byte , bukan karakter, menang sesuai dengan spesifikasi saat ini. Sepertinya Anda ingin pengkodean menjadi persyaratan, tapi saya tidak mengerti mengapa itu perlu. Apakah saya salah memahami komentar Anda?
Rainbolt

1
Berdasarkan beberapa jawaban yang hilang beberapa aturan, saya telah menambahkan dua contoh dan memindahkan seluruh contoh blok di bawah blok aturan untuk kejelasan tambahan.
Veskah

Jawaban:


5

GolfScript, 30 karakter

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

Jalankan online .

Contoh:

> 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 karakter EDIT : 38 poin (lihat bawah)

  #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#       #!#

Jika Anda tidak menghargai keterampilan seni saya yang mengerikan, inilah golfnya:

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

Yang ini melakukan hal-hal aneh dengan waktu evaluasi.

Pertama, BEGINkata kunci memaksa [get.comb, "." xx *]untuk dievaluasi terlebih dahulu, memasukkan ke dalam array daftar karakter yang membentuk "kode", diikuti oleh jumlah tak terbatas dari"." s.

Selanjutnya, getpada bagian akhir dievaluasi, dapatkan jumlah garis templat seni ASCII. The xxOperator mengulangi bagian pertama dari program ini berkali-kali. Ini lebih masuk akal ketika Anda menyadari bahwa code() xx count()pada dasarnya gula untuk code() for 1..count(): count()harus dievaluasi terlebih dahulu.

Akhirnya, getpada awal program mendapat garis templat seni ASCII dan mengganti setiap "*"dengan nilai bergeser dari awal array yang kita buat sebelum yang lainnya ({shift BEGIN …} ).

EDIT:

Diturunkan hingga 37 karakter, ditambah satu untuk pergantian baris perintah:

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

Ini adalah konsep yang sama seperti aslinya, -psaklar iterasi di setiap baris (setelah BEGINtelah membaca "kode"), dan mengganti semua *huruf s dengan huruf berikutnya dari "kode" sebelum mencetaknya. Format input untuk ini seharusnya tidak termasuk jumlah baris format.


6

Ruby 2.0, 53 52 karakter

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

Sesuai spek, tidak menggunakan parameter 'jumlah garis'.

Contoh dijalankan:

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

Keluaran:

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'
Bukan berarti Charles

@ Charles Saya sepertinya tidak bisa mendapatkan kesalahan itu dalam versi Ruby apa pun yang telah saya instal. Berikut kode yang berjalan pada IDEONE: ideone.com/3HG3Fb
Paul Prestidge

aneh. IDEONE bekerja dengan baik. Lagi pula, Anda dapat menyimpan char (spasi) dengan mengganti puts dengan $><<dan mengubah ,di akhir menjadi+
Bukan berarti Charles

@ Charles Panggilan yang bagus. Terima kasih!
Paul Prestidge

2

PowerShell , 63 86 83 82 byte

+20 byte terima kasih @Veskah

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

Cobalah online!

Kurang bermain golf:

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 byte

@ h adalah teks input

@ adalah polanya

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)

Cobalah online



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);

Menghasilkan karakter tambahan dalam input teks jika tidak digunakan dalam pola, menggunakan "." jika tidak cukup.

EDIT: dimodifikasi menjadi fungsi yang menerima teks dan pola


4
Bagus ... tapi ini menggunakan input kode-keras.
TheDoctor

Saya tidak yakin bagaimana menangani stdin dari JS, terutama dengan baris baru. Saran?
Mat

@ Mat Node? Monyet laba-laba?
Bukan berarti Charles

Mungkin membuatnya berfungsi ...
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))}
Michael M.

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))}

Catatan: Seperti yang disarankan oleh OP , saya menggunakan fungsi. Tetapi jika diperlukan untuk memiliki program, inilah solusi 93 karakter .

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

EDIT1: Perubahan besar, saya tidak tahu mengapa saya tidak menyadari ini untuk pertama kalinya: P Menyimpan 40 karakter.


Penggunaan :

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

Input Uji : (tanpa nomor opsional yang tidak dibutuhkan sesuai spesifikasi)

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

Keluaran :

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

Kode Tidak Terkunci :

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
             );
}

Akan sangat bagus untuk mendengar saran dari pengguna :)


1

Perl, 70 karakter

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

Atau, tanpa pemeriksaan batas, 56 karakter

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

Catatan, kode ini tidak menggunakan baris kedua seperti dalam spec, dan dapat disingkat menjadi tiga karakter <>;


1

Pesta, 166 156 111 106

Membaca dari input standar, tidak menghitung garis. Baris input pertama adalah kode yang ingin Anda masukkan ke dalam ascii art, semua baris berikutnya adalah ascii art, yang terdiri dari @karakter. Input memiliki panjang maksimal 999 karakter, dan tidak diizinkan mengandung garis miring ke depan . (Saya memilih untuk tidak menggunakan *atau #karena mereka memiliki arti khusus dalam Bash).

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

PERINGATAN: Program ini menggunakan file bernama p. Setelah menjalankan program, hapus p- ini akan membingungkan program saat Anda menjalankannya kedua kali.

Sebagian besar pekerjaan di sini dilakukan oleh

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

Baris pertama menggantikan yang pertama @dalam bidang ini dengan karakter pertama dari kode. Baris kedua menghapus karakter pertama dari kode.

Jika tidak ada cukup kode untuk mengisi bentuk, baris baru akan dicetak setelah keluaran utama ascii dibuat echo $i.


1

C, 98 , 91 karakter

Di sini solusi C yang cukup mudah dalam 100 karakter. Ini tidak menggunakan input jumlah baris. (Lain yang tidak dibutuhkan mendapat () akan diperlukan).

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);
}

Anda dapat menggunakan puts(s)alih-alih printf("%s",s)menyimpan 7 byte.
nyuszika7h

@ nyuszika7h Terima kasih! Tapi saya tidak tahu apakah tambahan \nitu masalah.
MarcDefiant

1

Python 2.7, 165 155 150 138 119 karakter

Oke, cukup banyak tapi saya kira itu cara terkecil untuk melakukannya dengan 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))

Sunting: versi 1.0.1 fungsional baru dengan byte yang lebih sedikit digunakan:

Edit2: map(r,['']*input()) alih-alih [r()for _ in[1]*input()]dan menghapus impor yang tidak digunakan

Edit3: '>'*input() alih-alih ['']*input()menyimpan satu karakter dan menambahkan karakter prompt untuk pola :)

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)

Anda dapat menggunakan (['.']+l).pop(0)bukannya (len(l)and l.pop(0)or'.')menyimpan 9 byte. Dan input()bukannya int(r())menyimpan 1 byte.
nyuszika7h

Terima kasih untuk input! Sayangnya saran pertama Anda tidak berfungsi karena menghasilkan titik selama panjang string> 0.
avall

Saya mengerti mengapa saran saya tidak benar. Coba (l+['.']).pop(0)saja, tetapi jika itu tidak berhasil, Anda masih bisa menyimpan 4 byte dengan menggunakan l andalih-alih len(l)and.
nyuszika7h

(l+['.']).pop(0)tidak menghapus elemen dari lkarakter jadi hanya karakter pertama yang dicetak tetapi lkondisinya bekerja :)
avall


0

05AB1E , 18 17 15 byte

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

Mengambil kode sebagai input pertama, pola sebagai yang kedua (dengan 0alih - alih #).

Cobalah secara online atau verifikasi semua kasus uji .

18 15 byte alternatif dengan mengambil input dalam urutan terbalik:

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

Cobalah online .

Penjelasan:

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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.