Gambarlah formasi bowling

44

Tujuan Anda adalah menampilkan seni ASCII dari formasi dalam bowling sepuluh pin di mana hanya beberapa pin yang tersisa. Bytes paling sedikit menang.

Puluhan pin berada dalam formasi segitiga:

O O O O         
 O O O   
  O O       
   O

Pin diberi label dari 1 hingga 10 sebagai:

7 8 9 10    
 4 5 6            
  2 3    
   1

Menggambar pin as Odan missing pin as ., formasinya 1 3 5 6 9 10adalah:

. . O O         
 . O O    
  . O       
   O

Memasukkan:

String yang dipisahkan oleh spasi yang mencantumkan subset nonempty dari angka 1 hingga 10 secara berurutan.

Keluaran:

Cetak formasi yang sesuai atau hasilkan sebagai string dengan linebreak.

Formasi harus rata dengan kiri layar. Setiap spasi putih baik-baik saja selama gambar yang terlihat benar. Baris kosong sebelum dan sesudah juga baik-baik saja.

Kasus uji:

>> 1 2 3 4 5 6 7 8 9 10

O O O O    
 O O O    
  O O    
   O

>> 7 10

O . . O    
 . . .   
  . .   
   .

>> 3 5 7 9 10

O . O O    
 . O .    
  . O    
   .

>> 1

. . . .    
 . . .    
  . .    
   O       
Tidak
sumber
Bisakah Anda menjamin bahwa setidaknya akan ada satu pin? Ini akan menghemat karakter untuk saya jika saya dapat tersedak input kosong.
undergroundmonorail
1
@undergroundmonorail Sudah dijamin: "nonempty subset"
xnor
Saya benar-benar merindukan itu, terima kasih :)
undergroundmonorail
[kode-bowling]? : P
mbomb007

Jawaban:

17

brainfuck - 617 616 604 byte

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

Ini menghabiskan waktu dua hari bagi saya. Saya pikir itu sepadan. Mungkin ada bagian yang bisa lebih golf dengan mengubah sel tempat penyimpanan sesuatu atau apa pun, tapi saat ini saya senang saya membuatnya berfungsi.

Program ini harus benar-benar berbeda jika pertanyaan tidak menentukan bahwa input akan diurutkan. Cara kerjanya adalah dengan membuat daftar 10 pin di sekitar pin yang diinput. Itu agak membingungkan tapi mungkin ini akan menjelaskannya dengan lebih baik:

If you input these pins:           [2, 3, 6, 8, 9]
First, the program does this:      [2, 3, 6, 8, 9] + [10]
Then this:                         [2, 3, 6] + [7] + [8, 9, 10]
Then this:                         [2, 3] + [4, 5] + [6, 7, 8, 9, 10]
Finally, this:                     [1] + [2, 3, 4, 5, 6, 7, 8, 9, 10]
To build this:                     [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Saat melakukan itu, ia mengingat pin mana yang diletakkan pengguna di sana dan mana yang diletakkan di sana. Strategi ini akan sangat sulit digunakan jika input tidak diurutkan.

Hal lain yang membuat penyortiran menjadi lebih mudah adalah mendeteksi angka 10. Karena brainfuck berurusan dengan byte individu, bukan "angka" per se, itu bisa saja menyebalkan, tetapi input yang diurutkan membuatnya lebih mudah bagi saya untuk berurusan. dengan. Alasannya ada hubungannya dengan bagaimana saya menyimpan data dalam program. Saya mengambil input satu karakter pada waktu dan mengurangi 32 dari hasilnya. Jika sel tidak nol setelah itu, saya bergerak maju 4 sel. sebelum diulang. Ini berarti bahwa saya mendapatkan byte input non-spasi setiap 4 sel, dan saya secara efektif menyimpan pin sebagai nomor mereka + 16. Namun, 10 membutuhkan dua byte untuk mengetik, jadi saya harus membuat case khusus. Jika input tidak diurutkan, saya harus melihat melalui pin, tetapi karena diurutkan maka akan selalu menjadi pin terakhir jika muncul. Saya memeriksa apakah (byte terakhir dari input + 1) == (byte terakhir dari input) dan jika demikian, itu harus 10. Saya menyingkirkan byte terakhir dan mengatur yang terakhir kedua untuk apa yang dipahami oleh sistem saya sebagai "10". Karakter'1'dan '0'tidak muat dalam satu byte, tetapi angka 26 pasti!

Menghasilkan trik hanya untuk membuat sesuatu bekerja sama sekali adalah bagian favorit saya menggunakan bahasa ini. :)

Jika Anda tertarik dengan cara kerja program ini secara lebih rinci, Anda dapat melihat program dengan komentar yang saya gunakan saat menulisnya untuk memastikan saya ingat apa yang dilakukan semuanya. Bahkan menulis komentar di brainfuck itu sulit, karena tidak ada sintaksis komentar. Alih-alih, setiap karakter kecuali yang <[+.,-]>berada di no-ops. Mudah untuk memperkenalkan bug dengan memasukkan .atau ,dalam komentar Anda secara tidak sengaja ! Itu sebabnya tata bahasanya sangat miring dan titik koma ada di mana-mana.

EDIT: Sebagai contoh betapa mudahnya ini gagal: Saya menggunakan "non-space" di salah satu komentar! Ketika saya menghapus semua karakter non-bf dari sumbernya, program yang biasa saya lakukan menyimpannya di -. Untungnya itu tidak merusak apa pun, tapi sekarang saya sudah menghapusnya untuk menghemat satu byte. :)

EDIT II: Sudah lama sejak saya menyentuh yang ini, haha. Dalam jawaban brainfuck lain di situs ini, saya perhatikan bahwa saya tidak sengaja menggunakan koma di versi komentar. Karena input sudah habis, ini mengatur sel saat ini ke 0 (ini tergantung implementasi, tetapi dalam pengalaman saya itu adalah perilaku yang paling umum). Saya memperbaiki bug, tetapi itu membuat saya berpikir. Cara idiomatis untuk mengatur sel ke 0 adalah [-](kira-kira while (*p) { *p--; }), yang dua byte lebih lama. Setiap kali semua input telah dibaca, saya dapat menggunakannya ,sebagai gantinya. Ini menyelamatkan saya 2 byte dalam jawaban itu, dan 12 dalam yang ini!

one flag at the very left; will be important later
+>>>>

all nonspace bytes of input separated by 3 empty cells; pin number `n` stored with value `n` plus 16
,[>++++[<-------->-]<[>>>>],]<<<<

test if last pin is 10
[>+<<+<+>>-]<[>+<-]+<+<<[>+>-<<-]>[<+>-]>

[
    if not: find 10 minus the number it is; put that many placeholder pins (cells with value 1) at the end
    ,+++++[>+++++<-]>>[<->-]<[>>>>>[>>>>]+[<<<<]<-]>>[<+>-]<<<
]>


[
    if so: get rid of '0' byte; convert '1' byte to 26 (10 plus 16)
    >>[,<]<<+++++++++<
]<<<

pointer now sitting on the cell with the second greatest pin that was inputted (ie not a placeholder)

;;;;;;;

[
    check for flag placed at the very beginning of the program; if present: break
    -[+>>-<]>
    [
        find ((pin to our right) minus 1) minus pin to our left
        move all pins left of us 4*(that value) cells and insert placeholder pins
        >>[<+<+>>-]<<<<[>+>-<<-]>[<+>-]>[<<[<<<<]>>>>[[<<<<+>>>>-]>>>>]<<<<+>>-]>[>+<-]
    ]

    find first non placeholder pin to our left
    there has to be one because we haven't hit the flag yet
    <<<[-[+>]+<<<<]>>>>-<<<<<
]>>>>>+

we have now added placeholder pins at the end and in the middle; all that's left is the beginning

subtract 17 from lowest pin and put that many placeholders to the left
++++[>----<-]>->[<+>>+<-]<[<<<[<<<<]+[>>>>]<-]>>[<+>-]

subtract 32 from an empty cell 2 to the left of the lowest pin; will be useful later
<[<<<<]>>>++++[<-------->-]>

placeholder pins have the value 1; real pins have a value somewhere between 17 and 26
normalize it by stepping through and setting every pin with value != 1 to 3 (0's ascii code is 2 higher than period so this will make it easier to print later)
[-[,+++>]+>>>[<<<->>]>]<<<<<[>-]>[>>]>>

start writing 32s across the board; hitting every second cell
that's every pin and the cell 2 to the right of each pin
this is done in such a way that it will only halt if adding 32 to a cell sets it to 0; which is why we subtracted 0 from an empty cell earlier
it will catch us and prevent an infinite loop
+[<++++[<++++++++>-]<]

now write 13 to each pin; this adds up to 46 or 48; which are exactly the ascii values we want
>>[+++++++++++++>>>>]

we happen to have made a 14; turn it into a 10 for a newline
<<<<----

we're so close now; i can taste it
we have a list of 10 pins; each one with the ascii value that needs to be written
we have 32 everywhere because we'll need spaces
we even have a newline

the only problem now is that our list looks like this:
;;;;;;;;;;;;;;;;;;;;;;;;
;;1 2 3 4 5 6 7 8 9 10;;
;;;;;;;;;;;;;;;;;;;;;;;;

and we need to print in this order:
;;;;;;;;;;;;;;;;;;;;;;;;
;;7 8 9 10 4 5 6 2 3 1;;
;;;;;;;;;;;;;;;;;;;;;;;;

it's a pretty simple fix
once we print a pin we obviously don't need to remember it any more
so we simply print the last 4 pins on the list; destroying them on the way
then we print the last 3; which have become the ones we want
then two; then one
<+++[<<+<<[<<+<<]+[>>>>]<<<<-]<<<<[-<<<<]

print pins 7 8 9 10
>[.,>>]

print pins 4 5 6
<<<<<[<<<<]<++++++++++<<.<+<<+<<+<<+<<+<[.,>>]

print pins 3 2
<<<<<[<<]>++++++++++<+<<+<<+<..<+<[.,>>]

print the final pin!! :)
<[<<]<...<<.
monmon bawah tanah
sumber
14

Python 2, 108 byte

def f(x):
 for i in 4,3,2,1:print" "*(4-i)+" ".join(".O"[i*~-i/2-~z in map(int,x.split())]for z in range(i))

Panggil dengan f("3 5 7 9 10").

iadalah nomor baris, dengan 4 menjadi baris pertama dan 1 adalah yang terakhir. zadalah pin ke-n pada baris itu, dengan 0 yang berarti itu adalah pin pertama di baris dan i-1berarti itu adalah pin terakhir di baris itu.

Retas utama adalah i*~-i/2-~z, yang mengkonversi (i, z) -> pin number. Misalnya, (4, 0) -> 7karena pin 7 adalah pin pertama pada baris 4 (baris pertama). Derivasinya seperti ini:

  • Kami ingin fungsi mengambil ike pin pertama di baris i, yaitu 4 -> 7, 3 -> 4, 2 -> 2, 1 -> 1. Ini dipenuhi oleh (i**2-i)/2 + 1, dan dengan demikian (i**2-i)/2 + 1 + zmemberikan nomor pin yang benar untuk input(i, z)

  • Kemudian sederhanakan:

(i**2-i)/2 + 1 + z
  = (i*(i-1))/2 + 1 + z
  = i*~-i/2 + 1 + z
  = i*~-i/2-~z

Pyth , 33 byte

V4~Z-4N+*dNjdm@".O"}+d-11Zrz7U-4N

Cobalah online.

Program ini secara kasar diterjemahkan menjadi:

z = input()
Z = 0

for N in range(4):
  Z += 4-N
  print(" "*N + " ".join(".O"[d+11-Z in map(int, z.split())] for d in range(4-N)))

(Berkat isaacg untuk tips)

Sp3000
sumber
Kode Pyth Anda dapat di-golf dengan dua cara: V4sama dengan FNU4, dan rz7setara dengan mvkcz\ .
isaacg
Ahaha terima kasih. Saya masih belum terbiasa dengan apa yang ada dan tidak di Pyth tanpa harus memeriksa dokumen sepanjang waktu.
Sp3000
107 byte sebagai program lengkap.
FlipTack
9

Pyth , 31

V4+*dNjdm?\O}+7+dZrz7\.rN4~Z-N4

Coba di sini .

V4 mengatur loop for, dengan N sebagai variabel di atas [0,1,2,3].

*dNmenyediakan spasi awal, karena dspasi.

Untuk menemukan lokasi pin, ia menggunakan +7+dZ- 7 + d + Z.

d aku s:

0 1 2 3
 1 2 3
  2 3
   3

sedangkan Z0 di baris pertama, -4 di baris kedua, -7 di baris ketiga dan -9 di baris keempat. Ini karena Zdimulai dengan 0, dan ~Z-N4dikurangi Zdengan 4, lalu 3, lalu 2.

Kemudian, ia memeriksa apakah lokasi pin di input, menggunakan }+7+dZrz7. rz7adalah pin yang diinginkan dalam bentuk daftar int.

Kemudian, itu menciptakan Ojika ada, dan .sebaliknya. Ini adalah ruang yang dipisahkan, dengan jd, dan dicetak secara implisit.

isaacg
sumber
5

Perl 5: 51 (50 + 1 untuk -p)

Menggunakan rbendera s///yang merupakan salah satu tambahan perl 5 terbaru.

#!perl -p
$_="7890
 456
  23
   1
"=~s!\d!'. '^a
x/$&\b/!egr
nutki
sumber
5

CJam, 48 41 byte

Wow, ini lama sekali

"6789345 12  0"S*7/N*[l~]:(s"O"erA,s"."er

Uji di sini.

Penjelasan

Pertama-tama kita membuat tata letak:

"6789345 12  0"       "Push this string.";
               S*     "Riffle with spaces.";
                 7/   "Split into substrings of length 7.";
                   N* "Join with newlines.";

Ini menghasilkan

6 7 8 9
 3 4 5 
  1 2  
   0

Dan sekarang kita mengganti karakter digit sesuai dengan input:

[l~]                 "Read the input and turn it into an array of integers.";
    :(s              "Decrement each number and turn the array into a string of digits.";
       "O"           "Push this string.";
          er         "Character transliteration, replaces the input digits with O.";
            A,s      "Create the string '0123456789'.";
               "."   "Push this string.";
                  er "Character transliteration, replaces all remaining digits with periods.";
Martin Ender
sumber
"789A456S23SS1":~S*7/N*[l~]'OerB,'.ersedikit lebih pendek.
Dennis
@Dennis Terima kasih. Saya tidak sepenuhnya yakin apakah eritu autocasting ke array saat itu.
Martin Ender
Oh benar Itu diterapkan di 0.6.4, yang lebih muda dari pertanyaan ini. "789A456S23SS1":~S*7/N*[l~]"O"erB,"."erberfungsi dengan baik di 0.6.2.
Dennis
5

Python 2, 97 94

Ini menggunakan fungsi terjemahan, yang memungkinkan seseorang untuk membuat pergantian karakter-untuk-karakter dalam sebuah string. Seperti tr in perl, kecuali untuk mengetik lebih lama. Saya mendapatkan daftar angka desimal dengan membuat string dari 9 hingga kekuatan 99.

lambda a:u"7890\n 456\n  23\n   1".translate({ord(n):u'.O'[n+' 'in a+' ']+' 'for n in`9**99`})
feersum
sumber
5

Javascript, 155

Golf pertama, mungkin bisa lebih pendek.

function f(i){q='replace',s='7 8 9 0\n 4 5 6\n  2 3\n   1';alert(s[q](RegExp(i[q]('10','0')[q](/ /g,'|'),'g'),function(a){return a?'O':a})[q](/\d+/g,'.'))}

telepon dengan

f('1 2 3 4 5 6 7 8 9 10')
f('1 5 10')
f('')

SUNTING

Versi ES6, 130

f=i=>{q='replace',s='7 8 9 0\n 4 5 6\n  2 3\n   1';alert(s[q](RegExp(i[q]('10','0')[q](/ /g,'|'),'g'),a=>a?'O':a)[q](/\d+/g,'.'))}

SUNTING

Versi ES6, 79 gagal

f=i=>alert('7890\n 456\n  23\n   1'.replace(/\d/g,a=>i.indexOf(a)<0?'. ':'O '))

Versi ES6, 72 77, tidak ada peringatan, hanya kembali

f=i=>'7890\n 456\n  23\n   1'.replace(/\d/g,a=>i.search(a+'\\b')<0?'. ':'O ')
merah-X
sumber
1
79 dan 72 rusak, keduanya gagal untuk input 10
edc65
@ edc65 ups, terima kasih, sudah diperbaiki.
red-X
Ooh, pandai menggunakan karakter batas kata, saya muncul dengan hampir persis sama (kecuali menggunakan .match). Ini yang paling elegan dari semuanya.
ninjagecko
4

Ruby, 91

x=(1..10).map{|i|i.to_s==$*[0]?($*.shift;?0):?.}
4.times{|i|puts (x.pop(4-i)*' ').center 8}

Cukup mengganti argumen baris perintah dengan .s dan 0s dan mencetaknya menggunakan loop 4 siklus.

Versi yang mudah dibaca

x = (1..10).map do |i|
  if i.to_s == ARGV[0]
    ARGV.shift
    "0"
  else
    "."
  end
end

4.times do |i|
  row = x.pop(4 - i)
  puts row.join(' ').center 8
end
britishtea
sumber
4

GNU sed, 75

  • Disimpan 6 byte berkat @Jordan.

Skor termasuk 1 ekstra untuk -ropsi:

s/^/7 8 9 10\
 4 5 6\
  2 3\
   1 /
:
s/([0-9]+)(.*)\1/O\2/
t
s/[0-9]+/./g

Masukan melalui STDIN:

$ echo 3 5 7 9 10 | sed -rf ./bowling.sed
O . O O
 . O .
  . O
   .    
$ 

Cobalah online .

Trauma Digital
sumber
GNU sed memungkinkan label kosong, sehingga Anda dapat menyimpan dua byte dengan menjatuhkan ls .
Jordan
Juga jika Anda mengubah 0ke 10pada baris 2, 1/ke 1 /pada baris 5, dan [0-9]ke [0-9]+pada baris 7 dan 9 Anda dapat menjatuhkan baris pertama selama 4 byte.
Jordan
@ Jordan Cool - seseorang sudah memberi tip tentang itu . Oh, tunggu ... ;-)
Digital Trauma
3

CJam, 40 39 byte

4,Sf*'-A*[q~]{('ot}/3,{)/(\s}%Sf*W%]zN*

Saya tahu ada cara yang lebih pendek, tidak punya waktu untuk mencari tahu sekarang.

Bagaimana itu bekerja:

4,Sf*'-A*[q~]{('ot}/3,{)/(\s}%Sf*W%]zN*
4,                                          "Get the array [0,1,2,3]";
  Sf*                                       "Covert each number to that many spaces to";
                                            "get ["", " ", "  ", "   "] array";
     '-A*                                   "String '----------'";
         [q~]                               "Input numbers in an array";
             {    }/                        "For each input number";
              ('ot                          "Put 'o' at the corresponding index";
                    3,                      "Array [0,1,2]";
                      {     }%              "For each of the above number";
                       )                    "Increment the number";
                        /                   "Split the string into pieces of that length";
                         (\s                "Take the first string and join the rest back";
                              Sf*           "Riffle each string in array with space";
                                 W%         "Reverse the array of strings";
                                   ]z       "Zip together the space array and this one";
                                     N*     "Join by new line";

Cobalah online di sini

Pengoptimal
sumber
3

APL (35)

⊖4 7⍴'.O'[1+⎕∊⍨⍳10]\⍨17110357⊤⍨28/2

Uji:

      ⊖4 7⍴'.O'[1+⎕∊⍨⍳10]\⍨17110357⊤⍨28/2
⎕:
      1 3 5 6 9 10
. . O O
 . O O 
  . O  
   O   

Penjelasan:

  • 17110357⊤⍨28/2: representasi 28-bit dari 17110357:

          4 7⍴17110357⊤⍨28/2
    0 0 0 1 0 0 0
    0 0 1 0 1 0 0
    0 1 0 1 0 1 0
    1 0 1 0 1 0 1
    
  • \⍨: Untuk setiap 0, beri ruang, dan untuk setiap1 , ambil item dari string di sebelah kiri.

  • ⎕∊⍨⍳10: Baca baris dari keyboard dan evaluasilah ( ), lalu periksa setiap angka dari 1 hingga 10 ( ⍳10) apakah itu terkandung dalam input (atau∊⍨ ).
  • '.O'[1+... ]: Tambahkan 1 ke setiap nilai (memberikan 1s dan 2s bukannya 0s dan 1s), lalu ganti setiap 1 dengan .dan setiap 2 denganO .
  • 4 7⍴: mengubah string yang dihasilkan menjadi matriks 4-oleh-7
  • : balikkan secara horizontal
marinus
sumber
3

Powershell: 109

Input dalam $ i

(7..10),(4..6),(2,3),1|%{$c=0}{$_|%{$o=(" "*$c++)}{$o="$o $(if($i.split() -contains $_){'O'}else{'.'})"};$o}

Itu tadi menyenangkan. Belajar banyak hal tentang cara kerja pipa juga.

Ben
sumber
3

Haskell: 163 160 byte

Ini menerima garis angka yang dipisahkan oleh spasi stdin.

m=map
y?x|x`elem`y="O "|0<1=". "
f y=putStr.unlines.zipWith(++)(m(`replicate`' ')[0..])$m(concat.m(y?))[[7..10],[4..6],[2,3],[1]]
main=getLine>>=f.m read.words

Tidak Disatukan:

layout :: [[Int]]
layout = [[7,8,9,10]
         ,[ 4,5,6  ]
         ,[  2,3   ]
         ,[   1    ]
         ]

indentBy :: Int -> String
indentBy n = replicate n ' '

indentLines :: [String] -> [String]
indentLines
  = zipWith (++)
            (map indentBy [0..])

bowling :: [Int] -> String
bowling pins
  = unlines
  . indentLines
  $ map (concatMap showPlace)
        layout
  where
    showPlace :: Int -> String
    showPlace index
      | index `elem` pins = "O "
      | otherwise         = ". "

parseInput :: String -> [Int]
parseInput = map read . words

main :: IO ()
main = do
  pins <- fmap parseInput getLine
  putStr (bowling pins)

Dan bonus:

C: 250 byte

Versi ini mengharapkan argumen baris perintahnya menjadi daftar angka.

#define w int
main(w
z,char**a){w
b[10]={1,3,2,6,5,4,10,9,8,7};w
q=9;for(w
k=4;k>0;--k){w
i;for(i=0;i<4-k;++i)printf(" ");for(i=0;i<k;++i,--q){w
g=0;w
c;for(w
p=1;p<z;++p){sscanf(a[p],"%d",&c);g|=b[q]==c;}c=g?'O':'.';printf("%c ",c);}printf("\n");}}
David
sumber
2

Perl, 73

$_="7 8 9 10\n 4 5 6\n  2 3\n   1";for$v(<>=~/\d+/g){s/$v/O/g};s/\d+/./g;print

Dan pendekatan bonus konyol yang tidak berjalan, 90 karakter:

srand(1488068);$i=<>;print+(($i=~/$_\b/?O:".")." "x rand 5)=~s/  /\n /r for 7..10,4..6,2,3,1
Eric Wastl
sumber
2

Mathematica, 109 byte

Fungsi:

f=(i=0;Reverse@Table[Row@Table[If[MemberQ[ToExpression/@StringSplit@#,++i],O,"."],{n}],{n,4}]~Column~Center&)

Dipanggil oleh:

f@"3 5 7 9 10"

Jika fungsi anonim diizinkan, ini dapat disingkat menjadi 105 byte :

i=0;Reverse@Table[Row@Table[If[MemberQ[ToExpression/@StringSplit@#,++i],O,"."],{n}],{n,4}]~Column~Center&

Jika input tidak harus berupa string yang dibatasi ruang, tetapi bisa berupa array angka dalam formulir {3,5,7,9,10}, ini dapat lebih pendek menjadi 79 byte :

i=0;Reverse@Table[Row@Table[If[MemberQ[#,++i],O,"."],{n}],{n,4}]~Column~Center&
kukac67
sumber
2

Bash murni (tanpa coreutils), 85

Penggantian pola sederhana:

f="7 8 9 0
 4 5 6
  2 3
   1"
a=${@/10/0}
f="${f//[${a// /}]/O}"
echo "${f//[0-9]/.}"

Daftar adalah input melalui args baris perintah.

Trauma Digital
sumber
2

Rebol - 117

s: array/initial 10"."b:""foreach n to-block input[s/:n:"0"]for n 4 1 -1[prin b print take/last/part s n append b" "]

Tidak Disatukan:

s: array/initial 10 "."
b: ""
foreach n to-block input [s/:n: "0"]
for n 4 1 -1 [prin b print take/last/part s n append b " "]
draegtun
sumber
2

Brainfuck, 179 byte

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

Diformat:

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

Mengharapkan input tanpa baris baru yang tertinggal.

Cobalah online.

Rekaman diinisialisasi dengan sepuluh node, masing-masing berisi satu diikuti oleh nol. Yang pertama adalah nilai awal pin, dan nol memfasilitasi navigasi dan bertindak sebagai pengganti untuk karakter ruang. Untuk setiap angka dalam input, pin tersebut bertambah 3; Perhatikan bahwa ord('O') - ord('.') = 33, dan selama fase pencetakan, nilai pin akan dikalikan dengan 11. (Penggandaan ini juga digunakan untuk menghasilkan karakter spasi.) Urutan pin dari kiri ke kanan pada kaset cukup 1terserah 10. Jika input diakhiri dengan a 10, koreksi dilakukan, karena 10awalnya diperlakukan sebagai a1 .

Setelah input diproses, yang negatif ditempatkan setelah setiap baris. Kemudian baris dicetak dalam satu lingkaran, dengan jumlah spasi terdepan ditentukan oleh jumlah baris yang sebelumnya diproses.

Mitch Schwartz
sumber
1

Clojure, 216 karakter (ugh)

Saya yakin ini bisa bermain golf lebih lanjut.

(let[s(map #(dec(read-string %))(.split(slurp *in*)" +"))](println(apply str(replace(apply hash-map(interleave(map #(char(+ 48 %))(range 10))(map #(if(some #{%}s)"O"".")(range 10))))"6 7 8 9\n 3 4 5\n  1 2\n   0"))))

Gunakan seperti ini:

echo -n "2 4 9 8 10 5" | clojure a-file-which-contains-this-program.clj

sumber
1

AWK: 96 byte

{gsub(/ /,"");a="6 7 8 9\n 3 4 5\n  1 2\n   0";gsub("["$0"]","O",a);gsub(/[0-9]/,".",a);print a}

catatan:

  • Pemisah spasi pada nilai input adalah opsional (tetapi berfungsi juga jika diperlukan)
  • Jumlahnya tidak harus berurutan
  • Masukan dibaca di STDIN
LeFauve
sumber
1

C # - 192 byte

Karena C #!

Saya mulai mencoba membangun output dengan matematika, tetapi metode ganti-token-in-string sederhana tampaknya paling baik untuk bahasa tingkat yang lebih tinggi. Ketergantungan Linq adalah gondrong tetapi masih lebih pendek dari menjaga counter dan melakukan pemeriksaan jangkauan.

using System.Linq;class A{static void Main(string[]a){var s=@"7 8 9 0
 4 5 6
  2 3
   1";for(int c=11;c-->1;)s=s.Replace((char)(48+c%10),a.Contains(""+c)?'O':'.');System.Console.Write(s);}}

EDIT: unix line returns (-3 bytes)

BMac
sumber
1

Scala, 150 148

def t(n:Any)=("G H I J D E F   B C     A"/:('A'to'J'))((j,i)=>j.replace(i,(if((n+" ").indexOf((i-64)+" ")>=0)'0'else'.'))).grouped(7).maxBy(println)

Menerima serangkaian string yang dibatasi ruang

Chad Retz
sumber
1

JavaScript ES6, 78 byte

F=i=>'7890\n 456\n  23\n   1'.replace(/\d/g,e=>'0.'[+!~i.search(e+'\\b')]+' ')

Gunakan cuplikan berikut untuk menguji. Ini menggunakan prompt dan peringatan dan notasi fungsi reguler untuk kemudahan pengujian.

i=prompt()
alert('7890\n 456\n  23\n   1'.replace(/\d/g,function(e){return'0.'[+!~i.search(e+'\\b')]+' '}))

NinjaBearMonkey
sumber
1

VB / Basic-229

Tujuan saya adalah mengalahkan java ^^

Dim f
Sub m()
f = " 1 2 3 4 5 6 7 8 9 10"
a = l(7, 10) + l(4, 6) + l(2, 3) + l(1, 1)
MsgBox a
End Sub
Function l(b, e)
r = Space(3 - (e - b))
For i = b To e
r = r + IIf(InStr(f, Str(i)), "0 ", ". ")
Next
l = r + vbCr
End Function

edit vbCr alih-alih chr (13)

r = r + Spasi (3 - (e - b))

singkatan jika

penggunaan fungsi alih-alih sub

sub MAIN () -> sub m ()

dwana
sumber
Bisakah Anda memasukkan panjang kode dalam byte dalam jawaban Anda?
ProgramFOX
Ya, tapi saya masih sedikit mengutak-atik kodenya
dwana
1

Jawa - 223 karakter

public class Pins {public static void main(String[] args) {String s = "7 8 9 0\n 4 5 6\n  2 3\n   1";for (String arg : args) {s = s.replace(arg.replace("10", "0"), "o");}s = s.replaceAll("\\d", ".");System.out.println(s);}}

Saya dulu suka cara ini, lalu saya sadar saya perlu hack kecil, masih seperti solusi saya.

public class Pins {
public static void main(String[] args) {
    String s = "7 8 9 0\n 4 5 6\n  2 3\n   1";
    for (String arg : args) {
        s = s.replace(arg.replace("10", "0"), "o");
    }
    s = s.replaceAll("\\d", ".");
    System.out.println(s);
}
}
JM Ottonello
sumber
1

K, 57 byte

Belum sangat kompetitif, tapi ini awal:

`0:((!4)#\:" "),',/'|0 1 3 6_(". ";"O ")@|/(1+!10)=/:(),.

Contoh penggunaan:

  `0:((!4)#\:" "),',/'|0 1 3 6_(". ";"O ")@|/(1+!10)=/:(),."3 5 7 9 10"
O . O O 
 . O . 
  . O 
   . 
  `0:((!4)#\:" "),',/'|0 1 3 6_(". ";"O ")@|/(1+!10)=/:(),."1"
. . . . 
 . . . 
  . . 
   O 

Saya mulai dengan mengevaluasi string input dengan .- untungnya, angka-angka yang dipisahkan ruang adalah daftar literal yang sah dalam K. Dengan mendahulukan daftar kosong ke hasil eval saya dapat memastikan itu adalah daftar bahkan dalam kasus pin tunggal. Lalu saya membuat vektor boolean yang mewakili posisi pin:

  (1+!10)=/:3 5 7 9 10
(0 0 1 0 0 0 0 0 0 0
 0 0 0 0 1 0 0 0 0 0
 0 0 0 0 0 0 1 0 0 0
 0 0 0 0 0 0 0 0 1 0
 0 0 0 0 0 0 0 0 0 1)
  |/(1+!10)=/:3 5 7 9 10
0 0 1 0 1 0 1 0 1 1

Lalu saya mengindeks ke daftar string untuk mendapatkan karakter ruang-empuk untuk setiap posisi pin.

  (". ";"O ")@0 0 1 0 1 0 1 0 1 1
(". "
 ". "
 "O "
 ". "
 "O "
 ". "
 "O "
 ". "
 "O "
 "O ")

Saya mengiris urutan itu menjadi baris ( _), membalikkannya ( |) dan bergabung bersama setiap fragmen ( ,/'):

  ,/'|0 1 3 6_(". ";"O ")@0 0 1 0 1 0 1 0 1 1
("O . O O "
 ". O . "
 ". O "
 ". ")

Sekarang mulai terlihat seperti pola yang kita inginkan. Yang tersisa hanyalah memakukan pada beberapa spasi utama untuk setiap baris ( ((!4)#\:" "),') dan mencetak baris ke stdout ( 0:).

JohnE
sumber
1

Pascal (FPC) , 165 byte

var f:string='. . . .'#10' . . .'#10'  . .'#10'   .';i:byte;z:array[1..10]of byte=(25,18,20,10,12,14,1,3,5,7);begin repeat read(i);f[z[i]]:='O'until eof;write(f)end.

Cobalah online!

Mengambil angka dari input standar, mencetak formasi ke output standar.

Pascal (FPC) , 175 byte

function f(q:array of byte):string;var i:byte;z:array[1..10]of byte=(25,18,20,10,12,14,1,3,5,7);begin f:='. . . .'#10' . . .'#10'  . .'#10'   .';for i in q do f[z[i]]:='O'end;

Cobalah online!

Fungsi yang melakukan hal yang sama, mengambil larik posisi pin dan mengembalikan string yang diformat.

AlexRacer
sumber
1

Powershell, 84 byte

$p='6789
 345
  12
   0'
-split$args|%{$p=$p-replace($_-1),'O '}
$p-replace'\d','. '

Skrip uji:

$f = {

$p='6789
 345
  12
   0'
-split$args|%{$p=$p-replace($_-1),'O '}
$p-replace'\d','. '

}

# one space at the end of each line with pins
@(
,("1 2 3 4 5 6 7 8 9 10",
@"
O O O O 
 O O O 
  O O 
   O 
"@)

,("7 10",
@"
O . . O 
 . . . 
  . . 
   . 
"@)

,("3 5 7 9 10",
@"
O . O O 
 . O . 
  . O 
   . 
"@)

,("1",
@"
. . . . 
 . . . 
  . . 
   O 
"@)
) | % {
    $s, $expected = $_
    $result = &$f $s
    $result-eq$expected
    $result
}

Keluaran:

True
O O O O
 O O O
  O O
   O
True
O . . O
 . . .
  . .
   .
True
O . O O
 . O .
  . O
   .
True
. . . .
 . . .
  . .
   O
mazzy
sumber
0

Java - 371 316 294 karakter

public class Bowling{public static void main(String[] a){boolean[] o=new boolean[10];int i;for(String s:a){i=Integer.parseInt(s)-1;o[i]=true;}for(int j=9;j>=0;j--){p((o[j]?"0 ":". "));p(j==6?"\n ":"");p(j==3?"\n  ":"");p(j==1?"\n   ":"");}p("\n");}static void p(String l){System.out.print(l);}}

Pertama kali melakukan ini, saya cukup yakin itu menyebalkan, tapi saya seorang pemula. Ini juga berfungsi ketika nomor tidak dipesan. Penomorannya salah tetapi saya tidak punya waktu untuk mencari tahu cara memperbaikinya ...

public class Bowling {
    public static void main(String[] args) {
        boolean[] ordened = new boolean[10];
        int i;
        for (String s : args) {
            i = Integer.parseInt(s) - 1;
            ordened[i] = true;
        }
        for (int j = 9; j >= 0; j--) {
            p((ordened[j] ? "0 " : ". "));
            p(j == 6 ? "\n " : "");
            p(j == 3 ? "\n  " : "");
            p(j == 1 ? "\n   " : "");
        }
        p("\n");
    }
    static void p(String l){
        System.out.print(l);
    }
}

input diberikan oleh java B 1 2 3 5 10misalnya. Output kemudian akan menjadi:

0 . . . 
 . 0 . 
  0 0 
   0 
Haroen Viaene
sumber
1
Penomorannya salah.
Pengoptimal
Saya akan mencoba memperbaikinya
Haroen Viaene
0

Japt -Rx , 29 19 18 17 bytes

5ÇÆ".O"gUø°TøÃÔû

Cobalah


Penjelasan

                      :Implicit input of integer array U
5Ç                    :Map each Z in the range [0,5)
  Æ                   :  Map the range [0,Z)
          °T          :    Increment T (initially 0)
        Uø            :    Does U contain T? (false=0, true=1)
   ".O"g              :    Get the character in the string ".O" at that index
            Ã         :  End mapping
             ¸        :  Join with spaces
              Ã       :End mapping
               Ô      :Reverse
                û     :Centre pad each element with spaces to the length of the longest
                      :Implicitly join with newlines, trim (not strictly necessary) and output
Shaggy
sumber