Karel J. AlphaBotシーケンスジェネレーター


14

スコア

このセクションは、提出物が入力されると記入されます。

正常

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

ボーナスラウンド

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

カレル・J・アルファボット

バックグラウンド

Javaの人気のある入門コースはKarel J. Robotです(私は自分で使用しています)。ロボットは、通りのグリッド(正の整数y座標)および通り(正の整数x座標)、およびグリッドに配置および保存できるビーパーと対話します(カレルとすべてのビーパーは格子上にのみ存在できることに注意してください)ポイント)。カレル(ロボット)は、5つのアクションのみを実行します。1歩進め、所定の位置で左に曲がり、ブザーを降ろし、ブザーを拾い、オフにします。

私のコンピューターサイエンスのクラスでは、最初の課題の1つとして、カレルをプログラムして、右に曲がり、向きを変え、1つずつ進めてブザーを鳴らす方法を組み合わせて実行する方法を学びました。数日後の課題は、これらのメソッドを使用して新しいメソッドを作成し、アルファベットの文字を作成することでした。

当然、この割り当てを終えたら、アルファベットのすべての文字と10桁の数字を作成するためのメソッドをさらに作成し、ロボットから一種のワードプロセッサを作成する方法を見つけ出す予定です。 STDINに入力され、ロボットは文字に似た方法でブザーをグリッドに配置します。

private void draw#各文字について書くたびに#、必要なコマンドのシーケンスの省略形を伝えるコメントを追加しました。

次のコマンド(擬似コードで記述)を自由に使用できます(説明-これらは唯一の有用なコマンドです)。

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"

条件

ロボットは次の順序で進む必要があります。

  • ロボットは、文字が描画される最小領域の5xN長方形の左下隅から開始します。
  • ロボットは手紙を描きます。
  • ロボットが長方形の右下隅に移動します。
  • ロボットは2つのスペースを右に移動し、北/上を向く必要があります

例を見てみましょう。描画したいとしAます。ロボットの位置は、その方向(北、南、東、西)を示す文字です。ロボットがビープ音のある場所にいる場合は文字が大文字になり、ロボットがビープ音のない場所にある場合は小文字になります。oは、ビープ音のあるスポットを表し、ビープ音の.ないスポットを表します。

後で見るように、Aこれです。

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

解決策の1つを次に示します。

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

mml4番目の箇条書きを完了する最後は、すべての文字に表示され、上記の提案されたソリューションのすべてに戻って別の2列を追加したくないため、暗黙的です。

したがって、作成する1つのソリューションApddrdddammmrdmrdddmrddddlmmlです。

これがソリューションである必要はないことに注意してください。アルゴリズムはすべての列を通過し、適切な場所にビーパーを配置し、他のビーパーが配置された場所または配置される場所に依存しません。アルゴリズムが何であっても、ロボットはグリッド上のスペースごとに1つのビープ音しか配置できません。


プログラム

プログラムは、文字のグリッドが何であるかの5xNグリッドを入力として受け取ります。入力にロボットがないことに注意してください。ロボットは、左下(南西)の角にあり、北を向いていると想定されます。

出力は、シーケンスの省略形である文字のシーケンスになります。

サンプル入力

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

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

サンプル出力

pddrdddammmrdmrdddmrddddlmml

prmmmlmlmmdrdrdddlmlmmdrdrmmmdrddddlmmlprdddlmldmmrmrmdmlmldmmrdrddddrmmmdlmml

これはコードゴルフです。標準のCGルールが適用されます。バイト単位の最短コードが優先されます。


ボーナスラウンド

ルール

ボーナスラウンドに参加したい場合は、コードの移動効率を高めてください!以下は、プログラムの実行時に作成される5x5のすべての文字のライブラリです。ボーナスラウンドの目的は、ABCDEFGHIJKLMNOPQRSTUVWXYZ可能な限り少ない動きを含むシーケンスを印刷するプログラムを書くことです。STDINへの入力はありません。コードは採点されますないコードの長さが、その上で「移動スコア。」移動スコアは、長方形内のすべてのポイントを訪れるスイーパーアルゴリズムを阻止するように設計されています。

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

手紙

.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

元のチャレンジと同じ手順に従う必要があります。文字は、各文字をスペースで区切って1つずつ描画する必要があります。

標準のCGルールが適用されます。最も低い移動スコアを持つエントリが勝ちます。




要約すると、両方のコードは基本的に同じことを行います。最初のコードはコード内の最小バイト数を使用し、2番目のコードは最小数の移動を使用する必要があります。


きちんとした挑戦-なぜあなたは投票されているのか分かりません
デウソビ

1
ありがとう@Deusovi。理由を説明してもらいたいので、意味をなさないものや改善できないものをすべて整理できます。
アークトゥルス

カレル(ロボット)は5つのアクションを実行するだけです」:「できる」が欠けていると思いますが、間違いなく5番目のアクションがありません。ボーナスラウンドが何であるかはわかりません。最高のソリューションを書いた人に賞金を授与するつもりですか?
ピーターテイラー

おそらく、コードゴルフチャレンジの代わりに、最小移動ゴルフチャレンジに変更しますか?これは効率に関するものだからです。
-LukStorms

1
限られた動きのセットでの最小限の動きの挑戦は、コードゴルフの部分なしではそれほど面白くない。最適なパスをBFSするのは非常に簡単です。
bopjesvla

回答:


5

perl -p0、60 56 54 + 2バイト

ゴルフ

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

ノート

/\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

の素敵な使い方は@-Perlでのゴルフヒントを共有するのに役立つかもしれません質問!
ドムヘイスティングス

2

JavaScript(ES6)、91

基本的な挑戦への最初の試み。

EcmaScript 6準拠のブラウザーで以下のスニペットを実行してテストします(Firefoxでテスト済み)

BONUS CHALLENGE ANSWER-完全なアルファベットのスコア= 869

Firefoxで以下のウィニペットを実行してテストします(より良いフルスクリーン)

固定入力/固定出力の課題が好きではないので、入力を試すことができます。覚えておいてください、文字のみが印刷されます。

// 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

OK!私はあなたを責めません。ボーナスを試みたのはあなただけです。
アークトゥルス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.