Карел Дж. Генератор последовательностей 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

Карел Дж. АльфаБот

Фон

Популярный вводный курс по Java - Карел Дж. Робот (я использую это сам). Робот взаимодействует с сеткой улиц (положительные целые y-координаты) и проспектов (положительные целые x-координаты), а также звуковыми сигналами, которые можно размещать и хранить в сетке (обратите внимание, что Karel и любые звуковые сигналы могут существовать только на решетке точки). Карел (робот) должен выполнять только пять действий: продвинуться на 1, повернуть налево на место, поставить звуковой сигнал, взять звуковой сигнал и выключиться.

На моем уроке информатики одним из наших первых заданий было запрограммировать Карела, чтобы он научился поворачивать направо, поворачиваться и выполнять комбинированное действие: двигаться вперед на 1 и нажимать бипер. Задание несколько дней спустя состояло в том, чтобы использовать эти методы и написать новые методы для производства букв алфавита.

Естественно, когда я закончил это задание, я написал больше методов, чтобы сделать каждую букву алфавита, а также десять числовых цифр, и я планирую выяснить, как сделать своего рода текстовый процессор из робота, где строка будет введен в 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 минимальной области, в которой будет нарисована буква.
  • Робот рисует письмо.
  • Робот перемещается в правый нижний угол прямоугольника.
  • Робот перемещается на два пробела вправо и должен быть направлен на север / вверх

Давайте работать через пример. Предположим, мы хотим нарисовать A. Местоположение робота - это буква, указывающая его направление (север, юг, восток, запад). Буква пишется с большой буквы, если робот находится на месте с бипером и строчными буквами, если робот находится на месте без бипера. oпредставляет пятна со звуковыми сигналами и .представляет пятна без звуковых сигналов.

Как мы увидим позже, Aэто так.

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

Вот одно из возможных решений.

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

Окончательное mmlзавершение четвертого пункта неявно, потому что оно появляется в каждой букве, и потому что я не хочу возвращаться и добавлять еще два столбца ко всему в предложенном выше решении.

Таким образом, одно решение , чтобы сделать Aэто pddrdddammmrdmrdddmrddddlmml.

Обратите внимание, что это не должно быть вашим решением. Ваш алгоритм может проходить через каждый столбец, размещая звуковые сигналы в нужных местах и ​​не полагаясь на то, где были или будут размещены другие звуковые сигналы. Независимо от того, какой у вас алгоритм, робот может разместить только один бипер на место в сетке.


Программа

Ваша программа примет в качестве входных данных сетку 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

Это код гольф, ребята. Применяются стандартные правила компьютерной графики. Самый короткий код в байтах побеждает.


Бонус Раунд

правила

Если вы хотите принять участие в бонусном раунде, убедитесь, что ваши коды эффективны! Ниже приведена библиотека всех 5х5 букв, которые моя программа создает при запуске. Цель бонусного раунда - написать программу, которая печатает последовательность, в 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
Спасибо @Deusovi. Хотелось бы, чтобы они объяснили почему, чтобы я мог прояснить все, что не имеет смысла, или улучшить это.
Арктурус

« Карел (робот) только для выполнения пяти действий »: я думаю, что вам не хватает « способностей », и вам определенно не хватает пятого действия. И я не уверен, что такое бонусный раунд: собираетесь ли вы наградить человека, который пишет лучшее решение?
Питер Тейлор,

Возможно, вместо того, чтобы бросить вызов игре в гольф, измените ее на игру в гольф с минимальным ходом? Поскольку речь идет об эффективности.
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

Тест запуска wnippet ниже в 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! Я не виню тебя. Вы единственный, кто попытался получить бонус.
Арктур
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.