Trình tạo trình tự Karel J. AlphaBot


14

Điểm số

Phần này sẽ được điền vào khi đệ trình được nhập.

Bình thường

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

Vòng thưởng

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

Karel J. AlphaBot

Lý lịch

Một khóa học giới thiệu phổ biến về Java là Karel J. Robot (Tôi đang sử dụng nó cho mình). Robot tương tác với một mạng lưới đường phố (tọa độ y dương) và đại lộ (tọa độ x nguyên dương) cũng như tiếng bíp, có thể được đặt và lưu trữ trên lưới (lưu ý rằng Karel và bất kỳ tiếng bíp nào chỉ có thể tồn tại trên mạng điểm). Karel (robot) chỉ thực hiện năm hành động: di chuyển về phía trước 1, rẽ trái tại chỗ, đặt một tiếng bíp, nhấc một tiếng bíp và tự tắt.

Trong lớp Khoa học Máy tính của tôi, một trong những nhiệm vụ đầu tiên của chúng tôi là lập trình Karel để học cách rẽ phải, quay đầu và thực hiện hành động kết hợp di chuyển về phía trước 1 và đặt một tiếng bíp. Một nhiệm vụ vài ngày sau đó là sử dụng các phương thức này và viết các phương thức mới để tạo ra các chữ cái của bảng chữ cái.

Đương nhiên, khi tôi hoàn thành bài tập này, tôi đã viết thêm các phương pháp để tạo ra mọi chữ cái trong bảng chữ cái, cũng như mười chữ số, và tôi dự định tìm ra cách tạo ra một trình xử lý văn bản từ robot, trong đó một chuỗi sẽ được nhập vào STDIN và robot sẽ đặt các tiếng bíp lên lưới theo cách giống với các chữ cái.

Mỗi lần tôi viết private void draw#cho mỗi ký tự #, tôi đã thêm một nhận xét sau nó sẽ cho tôi biết các chữ viết tắt cho chuỗi lệnh tôi cần.

Tôi có các lệnh sau (được viết bằng mã giả) theo ý của tôi (làm rõ - đây là những lệnh duy nhất lệnh hữu ích ).

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"

Điều kiện

Robot phải tiến hành theo thứ tự sau.

  • Robot bắt đầu ở góc dưới bên trái của hình chữ nhật 5xN có diện tích tối thiểu mà chữ cái sẽ được vẽ.
  • Robot vẽ bức thư.
  • Robot di chuyển đến góc dưới bên phải của hình chữ nhật.
  • Robot di chuyển hai không gian sang phải và phải quay mặt về hướng bắc / lên

Hãy làm việc qua một ví dụ. Giả sử chúng ta muốn vẽ A. Vị trí của robot là chữ cái chỉ hướng của nó (bắc, nam, đông, tây). Bức thư được viết hoa nếu robot ở vị trí có tiếng bíp và chữ thường nếu robot ở vị trí không có tiếng bíp. ođại diện cho các điểm với tiếng bíp và. đại diện cho các điểm không có tiếng bíp.

Như chúng ta sẽ thấy sau này, Alà đây.

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

Đây là một giải pháp có thể.

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

Trận chung kết mml để hoàn thành viên đạn thứ tư là ẩn vì nó xuất hiện trong mỗi chữ cái và vì tôi không muốn quay lại và thêm hai cột khác vào mọi thứ trong giải pháp đề xuất ở trên.

Vì vậy, một giải pháp để thực hiện Apddrdddammmrdmrdddmrddddlmml.

Lưu ý rằng đây không phải là giải pháp của bạn. Thuật toán của bạn có thể đi qua mọi cột, đặt tiếng bíp vào vị trí thích hợp và không phụ thuộc vào nơi mà tiếng bíp khác đã được đặt hoặc sẽ được đặt. Bất kể thuật toán của bạn là gì, robot chỉ có thể đặt một tiếng bíp trên mỗi khoảng trống trên lưới.


Chương trình

Chương trình của bạn sẽ lấy đầu vào là lưới 5xN về lưới của chữ cái là gì. Lưu ý rằng không có robot trên đầu vào; Robot được cho là ở góc dưới bên trái (phía tây nam), hướng về phía bắc.

Đầu ra sẽ là chuỗi các chữ cái là tốc ký cho chuỗi.

Đầu vào mẫu

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

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

Đầu ra mẫu

pddrdddammmrdmrdddmrddddlmml

prmmmlmlmmdrdrdddlmlmmdrdrmmmdrddddlmmlprdddlmldmmrmrmdmlmldmmrdrddddrmmmdlmml

Đây là mã golf, fellas. Quy tắc CG tiêu chuẩn được áp dụng. Mã ngắn nhất trong byte thắng.


Vòng thưởng

Quy tắc

Nếu bạn muốn tham gia vào vòng thưởng, hãy chắc chắn làm cho mã của bạn di chuyển hiệu quả! Dưới đây là một thư viện của tất cả các chữ cái 5x5 mà chương trình của tôi tạo ra khi nó chạy. Mục tiêu của vòng thưởng là viết một chương trình in một chuỗi cho ABCDEFGHIJKLMNOPQRSTUVWXYZcàng ít lần di chuyển càng tốt. Không có đầu vào cho STDIN. Mã sẽ được phân loại không phải theo độ dài của mã mà là "điểm di chuyển" của nó. Điểm di chuyển được thiết kế để ngăn cản các thuật toán quét truy cập mọi điểm trong hình chữ nhật.

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

Bức thư

.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

Phải tuân theo quy trình tương tự như thử thách ban đầu: các chữ cái phải được rút ra cùng một lúc với khoảng cách giữa mỗi chữ cái.

Quy tắc CG tiêu chuẩn được áp dụng. Nhập cảnh với số điểm di chuyển thấp nhất sẽ thắng.




Tóm lại, cả hai mã về cơ bản sẽ làm những việc giống nhau. Mã đầu tiên phải có số byte tối thiểu trong mã và mã thứ hai nên sử dụng số lần di chuyển nhỏ nhất.


Thử thách gọn gàng - không biết tại sao bạn lại bị hạ thấp.
Deusovi

1
Cảm ơn @Deusovi. Tôi ước họ giải thích lý do tại sao tôi có thể làm sáng tỏ bất cứ điều gì không có ý nghĩa hoặc cải thiện nó.
Arcturus

" Karel (robot) chỉ thực hiện năm hành động ": Tôi nghĩ bạn đang thiếu " có thể ", và bạn chắc chắn đang thiếu hành động thứ năm. Và tôi không chắc vòng quay thưởng là gì: bạn có định thưởng tiền thưởng cho người viết giải pháp tốt nhất không?
Peter Taylor

Có lẽ thay vì một thử thách golf mã thay đổi nó thành một thách thức golf di chuyển tối thiểu? Vì đây là về hiệu quả.
LukStorms

1
Thử thách di chuyển tối thiểu với một bộ di chuyển hạn chế không thú vị nếu không có phần chơi gôn. Nó sẽ khá dễ dàng để BFS đường dẫn tối ưu.
bopjesvla

Câu trả lời:


5

perl -p0, 60 56 54 + 2 byte

golf

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

ghi chú

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

Sử dụng tốt @-, có thể là một hữu ích để chia sẻ về các mẹo chơi golf trong câu hỏi Perl !
Dom Hastings

2

JavaScript (ES6), 91

Lần đầu tiên thử thách với những thách thức cơ bản.

Kiểm tra chạy đoạn mã dưới đây trong trình duyệt tuân thủ EcmaScript 6 (được thử nghiệm trong Firefox)

THƯỞNG THỬ THÁCH THƯỞNG THƯỞNG - Điểm cho bảng chữ cái đầy đủ = 869

Kiểm tra chạy wnippet bên dưới trong Firefox (toàn màn hình tốt hơn)

Vì tôi không thích những thách thức đầu vào cố định / đầu ra cố định , bạn có thể thử đầu vào của mình. Chỉ cần nhớ, chỉ có chữ cái sẽ được in.

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


Tiền thưởng thế nào?
Arcturus

@Eridan tiền thưởng đang diễn ra tốt đẹp. Thật không may, tôi cũng có một công việc ... :)
edc65

Đồng ý! Tôi không đổ lỗi cho bạn. Bạn là người duy nhất đã cố gắng nhận tiền thưởng.
Arcturus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.