วิธีง่ายๆในการเล่นรหัส ASCII ของศิลปะ!


18

งาน:

มีจำนวนมากของคำตอบเกี่ยวกับเว็บไซต์ที่มีการจัดเป็นศิลปะ ASCII เช่นเป็นคนนี้ โดยปกติแล้วการจัดเรียงจะดำเนินการด้วยตนเอง แต่โปรแกรมจะไม่ช่วยหรือไม่ :)

โปรแกรมของคุณจะมี 3 อินพุต:

  • รหัสเป็นหนึ่งบรรทัดเดียว
  • จำนวนบรรทัดในรูปแบบ (สามารถละเว้นได้หากไม่จำเป็น)
  • รูปแบบตัวเองเป็น*s หรือตัวละครอื่น

กฎ:

  • คุณต้องเขียนโปรแกรม (ไม่ใช่ฟังก์ชั่น) ที่อ่านจาก stdin
  • ข้อความถูกวางไว้จากซ้ายไปขวาต่อบรรทัด
  • หากมีข้อความไม่เพียงพอที่จะเติมลวดลายให้ใส่.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
ข้อสมมติฐานอะไรที่ควรทำเกี่ยวกับสถานที่ที่อนุญาตให้แทรกช่องว่างและบรรทัดใหม่โดยไม่ต้องเปลี่ยนซีแมนทิกส์ของโปรแกรม
Peter Taylor

1
@PeterTaylor ดูเหมือนว่าไม่มีวิธีการวาง / แยกรหัสดังนั้นฉันคิดว่าความหมายถูกละเว้น?
Martin Ender

1
ทำ "สามารถละเว้น" และ "หรือส่วนอื่น" ของข้อมูลจำเพาะหมายความว่าเรามีอิสระที่จะพูดระบุว่าจำนวนบรรทัดต้องถูกตัดออกและควรเปลี่ยนเครื่องหมายดอกจันโดยพูดแทนXสำหรับเรา โปรแกรมที่จะทำงาน?
Ilmari Karonen

1
@Bakuriu ฉันไม่เข้าใจความคิดเห็นของคุณ หากคุณเขียนโปรแกรมใน ASCII ตัวละครแต่ละตัวจะเป็นไบต์ หากคุณเขียนเป็น UTF-32 อักขระแต่ละตัวจะมีขนาด 4 ไบต์ รหัสที่สั้นที่สุดเป็นไบต์ไม่ใช่ตัวอักษรชนะตามข้อมูลจำเพาะปัจจุบัน ดูเหมือนคุณต้องการให้การเข้ารหัสกลายเป็นข้อกำหนด แต่ฉันไม่เห็นว่าทำไมจึงจำเป็น ฉันเข้าใจผิดความคิดเห็นของคุณหรือไม่?
Rainbolt

1
จากคำตอบบางข้อที่ขาดหายไปของกฎฉันได้เพิ่มสองตัวอย่างและย้ายบล็อกตัวอย่างทั้งหมดด้านล่างบล็อกกฎเพื่อความชัดเจนเพิ่มเติม
Veskah

คำตอบ:


5

GolfScript 30 ตัวอักษร

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

Run ออนไลน์

ตัวอย่าง:

> 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ได้อ่านใน "รหัส") และแทนที่ทั้งหมด*ด้วยตัวอักษรถัดไปจาก "รหัส" ก่อนที่จะพิมพ์ รูปแบบการป้อนข้อมูลสำหรับสิ่งนี้ไม่ควรรวมจำนวนบรรทัดของรูปแบบ


6

ทับทิม 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'
ไม่ใช่ชาร์ลส์ที่

@Charles ฉันไม่สามารถรับข้อผิดพลาดนั้นได้ใน Ruby รุ่นใด ๆ ที่ฉันติดตั้ง นี่คือรหัสที่ทำงานบน IDEONE: ideone.com/3HG3Fb
Paul Prestidge

แปลก. IDEONE ทำงานได้ดี อย่างไรก็ตามคุณสามารถบันทึกถ่าน (พื้นที่) โดยแทนที่puts ด้วย$><<และเปลี่ยน,ในตอนท้ายเพื่อ+
ไม่ว่าชาร์ลส์

@Charles โทรดี ขอบคุณ!
Paul Prestidge

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
ดีมาก ... แต่นี่ใช้การป้อนข้อมูลแบบตายตัว
TheDoctor

ฉันไม่แน่ใจว่าจะจัดการ stdin จาก JS ได้อย่างไรโดยเฉพาะกับการขึ้นบรรทัดใหม่ ข้อเสนอแนะ?
Matt

@Matt Node? ลิงแมงมุม?
ไม่ใช่ชาร์ลส์ที่

อาจทำให้ฟังก์ชั่น ...
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))}

หมายเหตุ: ตามคำแนะนำของ OPฉันใช้ฟังก์ชัน แต่ถ้ามันจำเป็นต้องมีโปรแกรมที่นี่เป็นวิธีการแก้ปัญหา 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''}<>

หมายเหตุรหัสนี้ไม่ได้ใช้บรรทัดที่สองเหมือนใน spec และสามารถย่อให้สั้นลงได้สามอักขระ <>;


1

ทุบตี, 166 156 111 106

อ่านจากอินพุตมาตรฐานไม่นับจำนวนบรรทัด บรรทัดแรกของการป้อนข้อมูลคือรหัสที่คุณต้องการใส่ลงในศิลปะ ASCII ทุกบรรทัดที่ตามมาคือศิลปะ ASCII ประกอบด้วย@ตัวละคร ข้อมูลที่ป้อนมีความยาวสูงสุด 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}

บรรทัดแรกจะแทนที่@อักขระตัวแรกใน art ด้วยอักขระตัวแรกของโค้ด บรรทัดที่สองจะลบอักขระตัวแรกของรหัส

ถ้าไม่มีรหัสพอที่จะเติมรูปร่างขึ้นบรรทัดใหม่จะถูกพิมพ์หลังจากที่การส่งออกศิลปะ ASCII echo $iหลัก


1

C, 98 , 91 ตัวอักษร

นี่คือวิธีแก้ปัญหา C ตรงไปตรงมาในความยาวไม่เกิน 100 ตัวอักษร สิ่งนี้ไม่ได้ใช้อินพุตนับบรรทัด (จำเป็นต้องได้รับสิ่งที่สองที่ไม่จำเป็น ())

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 ตัวอักษร

โอเคสวยมาก แต่ฉันคิดว่ามันเป็นวิธีที่น้อยที่สุดที่จะทำกับงูหลาม

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 เวอร์ชั่นใหม่ที่ใช้งานน้อยลง:

แก้ไข 2: 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 # Interactive คอมไพเลอร์) , 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"+ไปเพื่อผนวกอักขระพิเศษไว้ในบรรทัดเดียวกัน
Veskah

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.