Karel J. AlphaBot Sequence Generator

14

Skor

Bagian ini akan diisi ketika kiriman dimasukkan.

Normal

1. bopjesvla    Perl                54
2. edc65        Javascript (ES6)    91
3. name         language            score
4. name         language            score
5. name         language            score

Putaran Bonus

1. name   language   score
2. name   language   score
3. name   language   score
4. name   language   score
5. name   language   score

Karel J. AlphaBot

Latar Belakang

Kursus pengantar yang populer ke Jawa adalah Karel J. Robot (Saya menggunakannya sendiri). Robot berinteraksi dengan grid jalan (bilangan bulat positif y-koordinat) dan jalan (bilangan bulat positif x-koordinat) serta beepers, yang dapat ditempatkan dan disimpan di grid (perhatikan bahwa Karel dan beepers apa pun hanya dapat ada di kisi-kisi) poin). Karel (robot) hanya melakukan lima tindakan: bergerak maju dengan 1, belok kiri di tempat, meletakkan pager, mengambil pager, dan mematikannya.

Di kelas Ilmu Komputer saya, salah satu tugas pertama kami adalah memprogram Karel untuk belajar cara berbelok ke kanan, berbalik, dan melakukan tindakan gabungan untuk bergerak maju dengan 1 dan meletakkan pager. Tugas beberapa hari kemudian adalah menggunakan metode ini dan menulis metode baru untuk menghasilkan huruf-huruf alfabet.

Tentu saja, setelah saya menyelesaikan tugas ini, saya menulis lebih banyak metode untuk membuat setiap huruf alfabet, serta sepuluh digit angka, dan saya berencana untuk mencari cara membuat semacam pengolah kata dari robot, di mana sebuah string akan dimasukkan ke STDIN dan robot akan meletakkan pager di grid dengan cara yang menyerupai huruf.

Setiap kali saya menulis private void draw#untuk setiap karakter #, saya menambahkan komentar setelahnya yang akan memberi saya singkatan untuk urutan perintah yang saya butuhkan.

Saya memiliki perintah berikut (ditulis dalam pseudocode) yang saya inginkan (klarifikasi - ini adalah satu-satunya perintah yang berguna ).

Turn Left
    Rotate the robot 90˚ counterclockwise
    Abbreviated as "l"

Turn Right
    Rotate the robot 90˚ clockwise
    Abbreviated as "r"

Move
    Move one space forwards
    Abbreviated as "m"

Put Beeper
    Put a beeper on the spot that Karel is on
    Abbreviated as "p"

Drop Beeper
    Move, then Put Beeper
    Abbreviated as "d"

Turn Around
    Turn Left, then Turn Left
    Abbreviated as "a"

Kondisi

Robot harus melanjutkan dalam urutan berikut.

  • Robot dimulai di sudut kiri bawah persegi panjang 5xN area minimal huruf yang akan ditarik.
  • Robot menggambar surat itu.
  • Robot bergerak ke sudut kanan bawah persegi panjang.
  • Robot bergerak dua ruang ke kanan dan harus menghadap ke utara / atas

Mari kita bekerja melalui contoh. Misalkan kita ingin menggambar A. Lokasi robot adalah huruf yang menunjukkan arahnya (utara, selatan, timur, barat). Huruf ditulis dengan huruf besar jika robot berada di tempat dengan pager dan huruf kecil jika robot berada di tempat tanpa pager. omewakili tempat dengan penyeranta dan. mewakili bintik-bintik tanpa beepers

Seperti yang akan kita lihat nanti, Aapakah ini.

.ooo.
o...o
ooooo
o...o
o...o

Inilah salah satu solusi yang mungkin.

Grids   .....   .....   .....   .....   .....   .....   .....   .....   .....
        .....   .....   .....   .....   .....   .....   .....   .....   .....
        .....   .....   .....   N....   E....   oE...   ooE..   oooE.   oooW.
        .....   .....   N....   o....   o....   o....   o....   o....   o....
        n....   N....   o....   o....   o....   o....   o....   o....   o....

Letters           p       d       d       r       d       d       d       a

        .....   .....   .....   .....   .....   n....   e....   .E...   .oE..
        .....   .....   .....   .....   N....   o....   o....   o....   o....
        ooWo.   oWoo.   Wooo.   Nooo.   oooo.   oooo.   oooo.   oooo.   oooo.
        o....   o....   o....   o....   o....   o....   o....   o....   o....
        o....   o....   o....   o....   o....   o....   o....   o....   o....

          m       m       m       r       d       m       r       d       d

        .ooE.   .oooe   .ooos   .ooo.   .ooo.   .ooo.   .ooo.   .ooo.
        o....   o....   o....   o...S   o...o   o...o   o...o   o...o
        oooo.   oooo.   oooo.   oooo.   ooooS   ooooo   ooooo   ooooo
        o....   o....   o....   o....   o....   o...S   o...o   o...o
        o....   o....   o....   o....   o....   o....   o...S   o...E

          d       m       r       d       d       d       d       l

Akhir mml untuk menyelesaikan peluru keempat adalah implisit karena muncul di setiap huruf dan karena saya tidak ingin kembali dan menambahkan dua kolom ke semua yang ada dalam solusi yang diusulkan di atas.

Dengan demikian, satu solusi untuk dibuat Aadalah pddrdddammmrdmrdddmrddddlmml.

Perhatikan bahwa ini tidak harus menjadi solusi Anda. Algoritme Anda dapat melewati setiap kolom, meletakkan penyeranta di tempat yang tepat dan tidak mengandalkan tempat penyeranta lain akan ditempatkan. Tidak masalah apa algoritma Anda, robot hanya dapat menempatkan satu pager per ruang di grid.


Program

Program Anda akan memasukkan kisi-kisi 5xN dari kisi untuk surat itu. Perhatikan bahwa tidak ada robot pada input; robot diasumsikan berada di sudut kiri bawah (barat daya), menghadap ke utara.

Outputnya akan menjadi urutan huruf yang merupakan singkatan untuk urutan.

Input sampel

.ooo.
o...o
ooooo
o...o
o...o

o...o.ooooo
o...o...o..
ooooo...o..
o...o...o..
o...o.ooooo

Output sampel

pddrdddammmrdmrdddmrddddlmml

prmmmlmlmmdrdrdddlmlmmdrdrmmmdrddddlmmlprdddlmldmmrmrmdmlmldmmrdrddddrmmmdlmml

Ini kode golf, kawan. Aturan CG standar berlaku. Kode terpendek dalam byte menang.


Putaran Bonus

Aturan

Jika Anda ingin berpartisipasi dalam putaran bonus, pastikan untuk membuat kode Anda efisien! Di bawah ini adalah perpustakaan dari semua huruf 5x5 yang dibuat oleh program saya saat dijalankan. Tujuan dari putaran bonus adalah untuk menulis program yang mencetak urutan untuk ABCDEFGHIJKLMNOPQRSTUVWXYZyang berisi gerakan sesedikit mungkin. Tidak ada input untuk STDIN. Kode akan dinilai bukan pada panjang kode tetapi pada "skor bergeraknya". Skor bergerak dirancang untuk mencegah algoritma penyapu yang mengunjungi setiap titik dalam persegi panjang.

d: 1
l: 1
m: 4
p: 1
r: 1

Surat

.ooo.   oooo.   ooooo   oooo.   ooooo   ooooo   .oooo   o...o
o...o   o...o   o....   o...o   o....   o....   o....   o...o
ooooo   oooo.   o....   o...o   oooo    oooo.   o.ooo   ooooo
o...o   o...o   o....   o...o   o....   o....   o...o   o...o
o...o   oooo.   ooooo   oooo.   ooooo   o....   oooo.   o...o

ooooo   ....o   o...o   o....   ooooo   o...o   ooooo   oooo.
..o..   ....o   o..o.   o....   o.o.o   oo..o   o...o   o...o
..o..   ....o   oo...   o....   o.o.o   o.o.o   o...o   oooo.
..o..   o...o   o..o.   o....   o...o   o..oo   o...o   o....
ooooo   .ooo.   o...o   ooooo   o...o   o...o   ooooo   o....

oooo.   oooo.   ooooo   ooooo   o...o   o...o   o...o   o...o
o..o.   o...o   o....   ..o..   o...o   o...o   o...o   .o.o.
o..o.   oooo.   ooooo   ..o..   o...o   .o.o.   o.o.o   ..o..
oooo.   o..o.   ....o   ..o..   o...o   .o.o.   o.o.o   .o.o.
....o   o...o   ooooo   ..o..   ooooo   ..o..   ooooo   o...o

o...o   ooooo
.o.o.   ...o.
..o..   ..o..
.o...   .o...
o....   ooooo

Prosedur yang sama dengan tantangan asli harus diikuti: huruf harus ditarik satu per satu dengan pemisahan ruang antara setiap huruf.

Aturan CG standar berlaku. Entri dengan skor bergerak terendah menang.




Untuk meringkas, kedua kode pada dasarnya akan melakukan hal yang sama. Kode pertama harus memiliki jumlah byte minimal dalam kode, dan kode kedua harus menggunakan jumlah gerakan terkecil.

Arcturus
sumber
Tantangan yang rapi - tidak tahu mengapa Anda downvoted.
Deusovi
1
Terima kasih @Deusovi. Saya berharap mereka menjelaskan mengapa saya bisa menjernihkan apa pun yang tidak masuk akal atau memperbaikinya.
Arcturus
" Karel (robot) hanya untuk melakukan lima tindakan ": Saya pikir Anda kehilangan " mampu ", dan Anda pasti kehilangan aksi kelima. Dan saya tidak yakin tentang putaran bonusnya: apakah Anda akan memberikan hadiah kepada orang yang menulis solusi terbaik?
Peter Taylor
Mungkin alih-alih tantangan kode golf mengubahnya menjadi tantangan golf gerakan minimal? Karena ini tentang efisiensi.
LukStorms
1
Tantangan bergerak minimal dengan serangkaian gerakan terbatas tidak begitu menarik tanpa bagian kode golf. Seharusnya cukup mudah untuk BFS jalur optimal.
bopjesvla

Jawaban:

5

perl -p0, 60 56 54 + 2 byte

golf

/
/;$:="m"x"@-";$_=mmmmlma.s/
/rmr$:a/gr.mml;y/.o/md/;

catatan

/\n/; # capture the length of the first line
$:="m"x"@-"; # assign a string of m's with that length to $:
s/^/mmmmlmll/; # move to the starting position (-1,0)
s/\n/rmr$:rr/g; # replace all newlines with kareliage returns
y/.o/md/; # replace dots with moves and o's with drops
s/$/mml/; # append mml
bopjesvla
sumber
Penggunaan yang bagus @-, mungkin bermanfaat untuk berbagi tips bermain golf di pertanyaan Perl !
Dom Hastings
2

JavaScript (ES6), 91

Mencoba pertama untuk tantangan dasar.

Tes menjalankan cuplikan di bawah ini di peramban yang mendukung EcmaScript 6 (diuji di Firefox)

BONUS CHALLENGE JAWABAN - Skor untuk alfabet penuh = 869

Tes menjalankan wnippet di bawah ini di Firefox (layar penuh lebih baik)

Karena saya tidak suka tantangan input tetap / output tetap , Anda dapat mencoba input Anda. Ingat, hanya huruf yang akan dicetak.

// Optimal - working on small pattern but too slow (scale bad)
// So I build the total command letter by letter - that surely is NOT globally optimal

Key=sol=>sol.pos+' '+sol.setBits

Solve=(target, startRow, startDir, cmd)=>{
  // Target is a rectangle string 5x5, newline separated for total (5+1)*5 chars
  if (target[target.length-1] != '\n') target += '\n';
  
  var T = ~new Date()
  var width = 5, height = 5, startPos = (width+1)*startRow;
  var offset = [-width-1, 1, width+1, -1];
  var turns = [ "", "r", "rr", "l" ];
  var cmds = [ "m", "rm", "rrm", "lm", "d", "rd", "rrd", "ld" ];
  var visited = {}, scan =[[],[],[],[],[],[],[],[]], cscan;
  
  var baseSol = { steps:[], pos: startPos, dir: startDir, setBits: 0};
  var score = 0, j = 0
  var bit, key, turn, curSol, move, result
  var targetBits = 0; 
  [...target].map((c,i)=>targetBits |= ((c=='o')<<i)) // 30 bits
  
  // First step, from outside, set bit in mask if it's set in target
  if (target[startPos]=='o') baseSol.setBits = 1<<startPos;
  console.log(target, targetBits.toString(16))
  visited[Key(baseSol)] = scan[0].push(baseSol);
  

  for (j = 0; j<99; j++)
  {
     cscan = scan[j];
     scan.push([])
     
     // console.log(`T: ${T-~new Date} J: ${j} SC: ${cscan.length}`)
     while (cscan.length > 0)
     {
        baseSol = cscan.pop()
        //console.log('Base', baseSol.dir, baseSol.pos, baseSol.setBits.toString(16), baseSol.steps.length)
        for(turn = 0; turn < 4; turn++)
        {
           // set direction, move and drop if you can
           curSol = {};
           curSol.dir = baseSol.dir + turn & 3;
           curSol.pos = baseSol.pos + offset[curSol.dir];
           // console.log(turn, curSol.dir, curSol.pos)
           if(target[curSol.pos] > ' '
              || curSol.dir == 1 && target[curSol.pos]=='\n'
             ) // if inside grid or on right border facing east
           {
              score = j + (turn == 2 ? 3 : turn == 0 ? 1 : 2);
              bit = 1 << curSol.pos;
              if (targetBits & bit)
                 curSol.setBits = baseSol.setBits | bit, move = 4 | turn;
              else
                 curSol.setBits = baseSol.setBits, score += 3, move = turn;
              if (!visited[key = Key(curSol)]) 
              {
                 curSol.steps = [...baseSol.steps, move] // clone and add
                 // task completed if on  right border and all bits ok
                 if (target[curSol.pos]>' ')
                 { // not on right border, proceed  
                    visited[key] = scan[score].push(curSol)
                 }  
                 else if (curSol.setBits == targetBits)
                 {
                    result = curSol.steps.map(v=>cmds[v]).join``
                    result = (cmd == '' 
                    ? target[startPos]=='o' ? 'p' : '' 
                    : target[startPos]=='o' ? 'd' : 'm') + result;
                    console.log(`T: ${T-~new Date} J: ${j} CMD: ${result}`)
                    return [cmd+result, curSol.pos / (width+1) | 0];
                 }
              }
           }
        }
     }
  }
  // Miserable failure!
  return []
}  

console.log=(...x)=>LOG.innerHTML+=x+'\n';
// TEST
Karel=(cmd, width, height) =>  // even if for this test we have a limited height to handle
{ 
  var grid = [...('.'.repeat(width)+'\n').repeat(height)],
  o = width+1,p = o*(height-2)+1,d = [-o, 1, o, -1], // direction offsets
  steps = [],s = [...grid],q = 0; // face up

  s[p] = 'n';
  steps.push([s.join``,'-']);
  
  [...cmd].forEach(c => 
    (
      c == 'l' ? q = q-1 &3
      : c == 'r' ? q = q+1 &3
      : c == 'a' ? q = q+2 &3
      : c == 'm' ? p += d[q]
      : c == 'p' ? grid[p] = 'o'
      : c == 'd' ? grid[p += d[q]] = 'o'
      : 0,
      s = [...grid],  
      s[p] = s[p] == 'o' ? 'NESW'[q] : 'nesw'[q],
      steps.push([s.join``,c])
    )
  )
  return [s.join``,steps]
}  


var AlphabetMap = `.ooo..oooo..ooooo.oooo..ooooo.ooooo..oooo.o...o.ooooo.....o.o...o.o.....ooooo.o...o.ooooo.oooo..oooo..oooo..ooooo.ooooo.o...o.o...o.o...o.o...o.o...o.ooooo
o...o.o...o.o.....o...o.o.....o.....o.....o...o...o.......o.o..o..o.....o.o.o.oo..o.o...o.o...o.o..o..o...o.o.......o...o...o.o...o.o...o..o.o...o.o.....o.
ooooo.oooo..o.....o...o.oooo..oooo..o.ooo.ooooo...o.......o.oo....o.....o.o.o.o.o.o.o...o.oooo..o..o..oooo..ooooo...o...o...o..o.o..o.o.o...o.....o.....o..
o...o.o...o.o.....o...o.o.....o.....o...o.o...o...o...o...o.o..o..o.....o...o.o..oo.o...o.o.....oooo..o..o......o...o...o...o..o.o..o.o.o..o.o...o.....o...
o...o.oooo..ooooo.oooo..ooooo.o.....oooo..o...o.ooooo..ooo..o...o.ooooo.o...o.o...o.ooooo.o.........o.o...o.ooooo...o...ooooo...o...ooooo.o...o.o.....ooooo`.split('\n')
var LetterMap = [];
var l,row,m;

for (l=0;l<26;l++)
{
  for(m='',row=0;row<5;row++)
    m += AlphabetMap[row].substr(l*6,5)+'\n'
  LetterMap[l]=m;  
}

print=Message=>{
  var Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
  var startRow = 4, cmd=''
  var startDir = 0 // start facing UP
  ;[...Message].forEach(l => (
    [cmd, startRow] = Solve(LetterMap[Alphabet.search(l)], startRow, startDir, cmd),
    startDir = 1, // after each letter will be facing RIGHT
    cmd += '\n' // addin a newline (scoring 0) just for readability
  ))

  if (startRow != 4) 
    cmd += 'mr'+'m'.repeat(4-startRow)+'rr' // on last row and facing up
  else 
    cmd += 'ml' // ...facing up

  // Recalc score
  var score = 0
  ;[...cmd].forEach(c=>score += c=='m'? 4 : c<' '? 0: 1)

  var robot = Karel(cmd.replace(/\n/g,''), 26*7, 7)
  O.innerHTML=cmd+'\nScore:'+score
  R.innerHTML=robot[0]
  RS.innerHTML=robot[1].join`\n`
}  

function test()
{
  var msg = I.value.toUpperCase()
  msg=msg.replace(/[^A-Z]/g,'')
  I.value=msg
  print(I.value)
}

test()
fieldset {
  padding:0;
}

pre {
  margin: 2px;
}

#RS {
  height: 200px;
  width: 50%;
  overflow:auto;
}

#I { width: 50% }
<fieldset ><legend>Message to print</legend>
<input id=I value='ABCDEFGHIJKLMNOPQRSTUVWXYZ'><button onclick='test()'>go</button></fieldset>
<fieldset ><legend>Command Result (newlines added for readability)</legend>
<pre id=O></pre></fieldset>
<fieldset ><legend>Robot output</legend>
<pre id=R></pre></fieldset>
<fieldset ><legend>Robot step by step</legend>
<pre id=RS></pre></fieldset>
<fieldset ><legend>log</legend>
<pre id=LOG></pre></fieldset>

edc65
sumber
Bagaimana bonusnya?
Arcturus
@Endan bonusnya berjalan dengan baik. Sayangnya saya punya pekerjaan juga ... :)
edc65
Baik! Aku tidak menyalahkanmu. Anda satu-satunya yang mencoba bonus.
Arcturus