Что окружает мою плитку Сапер?

31

Сапер - игра-головоломка, в которой мины спрятаны вокруг доски с неописуемыми тайлами с целью определения местоположения всех мин. Нажатие на мину проигрывает игру, но нажатие на любую другую плитку покажет число от 0 до 8, которое указывает, сколько мин непосредственно окружает ее.

Для данного числа вы должны отобразить случайную * возможную комбинацию пустых тайлов и мин, окружающих его. Это должно быть в виде массива 3х3. Центральная плитка должна быть числом мин, взятых в качестве входных данных.

* Должен иметь ненулевой шанс для всех комбинаций.


Примеры

_ = blank square
X = mine

0

___
_0_
___

1

_X_
_1_
___

1

___
_1_
X__

___
_1_
__X

4

_X_
X4X
_X_

4

X_X
_4_
X_X

4

___
X4X
X_X

8

XXX
X8X
XXX

вход

  • Количество мин, окружающих центр плитки (0-8)

Выход

  • Любая разумная форма вывода, которая отображает массив плиток 3х3

Другие правила

  • Каждая комбинация не должна иметь равные шансы на успех. Просто должна быть ненулевая вероятность того, что каждая комбинация произойдет при выполнении вашей программы.
  • Любые 2 символа могут быть выбраны для шахты и пустой плитки.
  • Это код гольф, программа с наименьшим количеством байтов выигрывает.
aoemica
источник
«Любые 2 символа могут быть выбраны для шахты и пустого тайла», мы можем все еще использовать, скажем, 1и 0?
Джонатан Аллан
3
@JonathanAllan Я скажу да, случаи ввода 0/1 могут быть немного запутанными, но я не думаю, что это имеет большое значение.
Aoemica
плоский 9-элементный список является «разумной формой вывода»?
Час Браун
@ChasBrown нет, плоский список на самом деле не эквивалентен.
Aoemica

Ответы:

4

Желе , 9 байт

<Ɱ8Ẋs4js3

Попробуйте онлайн!

пустой = 1
мой =0

Обратите внимание, что 1и 0являются целыми числами.

Еще одно замечание: это несколько похоже на 10-байтовый ответ Джонатана Аллана, но на него это никак не влияет, и механизм, если вы обратите пристальное внимание, на самом деле более отличается, чем на первый взгляд.

Эрик Outgolfer
источник
Тьфу, я пропустил трюк :)
Джонатан Аллан
@JonathanAllan Вы верите, что это достаточно близко к вашему? Суффикс в любом случае тот же ...
Эрик Outgolfer
1
Это немного по-другому. Если я читаю пост и нахожу быстрый гольф, я комментирую; если я просто пытаюсь решить проблему, которую я публикую. Я отправил идентичный код раньше независимо.
Джонатан Аллан
@JonathanAllan Мой подход к этому немного отличается, если я обнаружу, что мое независимое решение на самом деле почти такое же, как у кого-то другого, но с немного другим элементом, который сохраняет один или два байта (возникает субъективное мнение), я комментирую, в противном случае я outgolf. Вот почему я спросил, но вы, кажется, предпочитаете, чтобы я разместил это здесь, так что ...
Эрик Аутгольфер
9

APL (Dyalog Unicode) , 28 15 байт

-13 байт благодаря ngn!

{3 35⌽⍵,⍵≥8?8}

Объяснение:

{...}Прямая функция (D-Fn) является ее правильным аргументом.

8?8 Раздайте 8 случайных чисел из списка 1..8:

      8?8                         
7 2 1 8 4 6 5 3

⍵≥ аргумент больше или равен каждому из них?

      5  7 2 1 8 4 6 5 3   
0 1 1 0 1 0 1 1

⍵, добавьте аргумент в логический список:

      5 , 0 1 1 0 1 0 1 1
5 0 1 1 0 1 0 1 1

5⌽ поверните список на 5 позиций влево, чтобы аргумент находился в центре:

      5  5 0 1 1 0 1 0 1 1
1 0 1 1 5 0 1 1 0

3 3⍴ измените список в матрицу 3x3:

      3 3  1 0 1 1 5 0 1 1 0
1 0 1
1 5 0
1 1 0

Попробуйте онлайн!

J 15 байт

Также много байтов благодаря ngn!

3 3$5|.],]>8?8:

Попробуйте онлайн!

Гален Иванов
источник
1
(8↑1⍴⍨⍵)[8?8]-> ⍵>8?8(при условии ⎕io←0)
нгн
1
3 3⍴1↓,⍵,2 4⍴->3 3⍴5⌽⍵,
СПП
@ngn Спасибо! Мне стыдно за мою многословную попытку ...
Гален Иванов
1
не надо стыдиться :) спасибо - этот ответ дал мне возможность выучить немного J
ngn
1
тот ответ J действительно прекрасен.
Иона
8

JavaScript (ES6), 67 байт

Более короткая версия, предложенная @tsh

Пустые слоты есть 0, мины есть 1.

n=>`___
_${t=9,n}_
___`.replace(/_/g,_=>n-(n-=Math.random()<n/--t))

Попробуйте онлайн!


Оригинальная пробная версия, 78 байт

Пустые слоты есть _, мины есть 7.

f=(n,o=`___
_${k=n}_
___`.replace(/_/g,c=>Math.random()<.5?--k|7:c))=>k?f(n):o

Попробуйте онлайн!

комментарии

f = (                         // f = recursive function
  n,                          // n = input
  o = `___\n_${k = n}_\n___`  // o = minesweeper field / k = backup of n
    .replace(/_/g, c =>       // for each underscore character c in o:
      Math.random() < .5 ?    //   random action:
        --k | 7               //     either decrement k and yield 7
      :                       //   or:
        c                     //     let the underscore unchanged
    )                         // end of replace()
) =>                          //
  k ?                         // if k is not equal to 0:
    f(n)                      //   try again
  :                           // else:
    o                         //   stop recursion and return o
Arnauld
источник
6

Желе ,  13  10 байт

8Ẉ>RẊs4js3

Возвращенный список списков имеет отображаемое целое число в центре, окруженное 0 и 1, представляющими мины и пробелы соответственно.

Попробуйте онлайн! (нижний колонтитул довольно печатает массив)

Как?

8Ẉ>RẊs4js3 - Link: integer, n                   e.g.  3
8          - eight                                    8
 Ẉ         - length of each (implicit range of eight) [1,1,1,1,1,1,1,1]
   R       - range of n                               [1,2,3]
  >        - greater than? (vectorises)               [0,0,0,1,1,1,1,1]
    Ẋ      - shuffle                                  [1,1,1,0,0,1,1,0]
     s4    - split into chunks of 4                   [[1,1,1,0],[0,1,1,0]]
       j   - join (with n)                            [1,1,1,0,3,0,1,1,0]
        s3 - split into chunks of 3                   [[1,1,1],[0,3,0],[1,1,0]]
Джонатан Аллан
источник
1
Как небольшая заметка, ŒHтакже работает вместо s4.
Мистер Кскодер
; s4s3 также работает
dylnan
@dylnan Я действительно написал с TIO, имеющим тот же код в одной точке во время игры в гольф (но быстро отложил его, чтобы мне не пришлось переписывать объяснение).
Джонатан Аллан
6

Pyth, 16 14 байтов

c3jQc2.S.[d8*N

Сохранено 2 байта благодаря isaacg.
Использует места для безопасных мест и цитаты для мин.
Попробуй здесь

объяснение

c3jQc2.S.[d8*N
            *NQ     Get (implicit) input number of quotes...
        .[d8        ... and pad to length 8 with spaces.
      .S            Shuffle.
  jQc2              Stick the input in the middle.
c3                  Split into three.

источник
.[d8вместо>8+*8d
Исаак
5

Oracle 18 SQL, 230 байт

Не язык игры в гольф, но ...

WITH v(v)AS(SELECT*FROM SYS.ODCINUMBERLIST(0,1))SELECT v.v||b.v||c.v||'
'||d.v||n||e.v||'
'||f.v||g.v||h.v
FROM n,v,v b,v c,v d,v e,v f,v g,v h
WHERE v.v+b.v+c.v+d.v+e.v+f.v+g.v+h.v=n
ORDER BY DBMS_RANDOM.VALUE
FETCH NEXT ROW ONLY

Входное значение находится в таблице nсо столбцом n:

CREATE TABLE n(n) AS
SELECT 7 FROM DUAL;

Попробуйте онлайн - войдите на https://livesql.oracle.com и вставьте его в рабочий лист.

Выход:

V.V||B.V||C.V||''||D.V||N||E.V||''||F.V||G.V||H.V
-------------------------------------------------
101 
171 
111

Чтобы получить все возможные комбинации (183 байта):

WITH v(v)AS(SELECT*FROM SYS.ODCINUMBERLIST(0,1))SELECT v.v||b.v||c.v||'
'||d.v||n||e.v||'
'||f.v||g.v||h.v
FROM n,v,v b,v c,v d,v e,v f,v g,v h
WHERE v.v+b.v+c.v+d.v+e.v+f.v+g.v+h.v=n

Выход:

V.V||B.V||C.V||''||D.V||N||E.V||''||F.V||G.V||H.V
-------------------------------------------------
111 
171 
110

111 
171 
101

111 
171 
011

111 
170 
111

111 
071 
111

110 
171 
111

101 
171 
111

011 
171 
111
mt0
источник
3

Japt, 13 байт

çÊú8 öÊi4U ò3

Попытайся


объяснение

                   :Implicit input of integer U
 Ê                 :"l"
ç                  :Repeat U times
  ú8               :Pad right to length 8
    öÊ             :Random permutation
       i4U         :Insert U at index 4
            ò3     :Split at every 3rd character
мохнатый
источник
3

QBasic 1.1 , 206 186 байт

RANDOMIZE TIMER
INPUT N
O=N
Z=8-N
FOR I=0TO 7
IF O*Z THEN
R=RND<.5
O=O+R
Z=Z-1-R
A(I)=-R
ELSEIF O THEN
O=O-1
A(I)=1
ELSE
Z=Z-1
A(I)=0
ENDIF
NEXT I
?A(0)A(1)A(2)
?A(3)N;A(4)
?A(5)A(6)A(7)

-20 благодаря DLosc (недавно опубликованная игра в гольф).

Пусто = 0
Мой =1

Обратите внимание, что 0и1 являются целыми числами, но я все равно использую STDOUT, так что ...

Вывод выглядит так:

 A  B  C
 D  x  E
 F  G  H

Где AH - 0/1, а x - вход.

Эрик Outgolfer
источник
Хороший трюк, работа с выигрышными числами QBasic с использованием чисел для шахты и пустого тайла!
DLosc
3

Древесный уголь , 19 байт

W¬⁼ΣIKA⁸«E³⭆³‽²↑↗↖θ

Попробуйте онлайн! Ссылка на подробную версию кода. Используется 0для шахты, 1для пустого пространства. Объяснение:

     KA             Peek the entire canvas
    I               Cast to integer
   Σ                Take the sum
       ⁸            Literal 8
  ⁼                 Equals
 ¬                  Logical Not
W       «           While
          ³ ³       Literal 3
         E          Map over implicit range
           ⭆        Map over implicit range and join
              ²     Literal 2
             ‽      Random element of implicit range
                    Implicitly print on separate lines
               ↑↗↖θ Print the original input in the middle
  • Peek возвращает массив строк, который Sum просто объединяется, поэтому сначала мы должны привести к целому числу. ( Sum(Sum(PeekAll()))также работает.)
  • Sum возвращается None для пустого массива (первый контур), поэтому единственное безопасное сравнение Not(Equals(...)).
  • Nilary Random всегда возвращается 0, хотя в ее документации сказано иначе.

Альтернативное решение, было 19 байт, теперь 17 байт после исправления Charcoal:

θ←9W⁻ΣIKA⁸UMKMI‽²

Попробуйте онлайн! Ссылка на подробную версию кода. Использует 0для шахты,1для пустого пространства. Объяснение:

θ

Распечатайте исходные данные.

←9

Печать 9влево. Это перемещает курсор назад к исходному вводу, а также инициирует хотя бы одну итерацию цикла while (в противном случае ввод 8ничего не будет делать).

W⁻ΣIKA⁸

Повторите, пока разница между суммой всех цифр на холсте и 8 не равна нулю:

UMKMI‽²

Замените каждого из окружающих символов случайным образом на 0или 1.

Нил
источник
3

R , 67 63 62 59 байт

matrix(c(sample(rep(1:0,c(n<-scan(),8-n))),n),6,5)[2:4,1:3]

Попробуйте онлайн!

Использует 1и 0. Создайте n* 1 +(8-n)* 0вектор, перемешайте его, добавьте n, создайте большую матрицу, показанную ниже (где a...iобозначены элементы исходного вектора), и извлеките правильную подматрицу, показанную в верхнем регистре:

     [,1] [,2] [,3] [,4] [,5]
[1,] "a"  "g"  "d"  "a"  "g" 
[2,] "B"  "H"  "E"  "b"  "h" 
[3,] "C"  "I"  "F"  "c"  "i" 
[4,] "D"  "A"  "G"  "d"  "a" 
[5,] "e"  "b"  "h"  "e"  "b" 
[6,] "f"  "c"  "i"  "f"  "c"
Jayce
источник
На один байт короче:matrix((c(sample(rep(1:0,c(n<-scan(),8-n))),n))[c(1:4,9:5)],3)
Грегор
1
@ Грегор, вы правы, массив, вероятно, является разумной формой вывода для отображения массива :)
JayCe
2

Python 2 , 93 байта

from random import*
def f(n):a=[1]*n+[0]*(8-n);shuffle(a);a[4:4]=[n];return zip(*[iter(a)]*3)

Попробуйте онлайн!

0для пустых; 1для шахты; и nдля себя.

Час Браун
источник
Использование iterумно!
Джонатан Аллан
@Jonathan Allan: xnor показал мне это только на днях.
Час Браун
2

Атташе , 51 байт

{[3,3]&Rotate[Sample[{Sum@_=_2}&_\BinBelow@8]'_,4]}

Попробуйте онлайн!

объяснение

Аналогично ответу Галена на J / APL , основной метод состоит в том, чтобы сгенерировать массив из 1 и 0 с правильным числом мин, вставить вход, добавив его в конец, вращая массив так, чтобы вход находился в центре, а затем преобразование в матрицу 3х3.

Часть 1: генерация двоичного массива

Есть много способов сделать это, но я в основном сталкивался с двумя типами: грубая сила и отбор.

Основной метод грубой силы выглядит следующим образом:

NestWhile[{Random[8&2]},0,{Sum@_/=_2}&_]

Это генерирует случайные массивы из 8 двоичных цифр ( Random[8&2]), в то время как их суммы не равны входным {Sum@_/=_2}&_. Это немного многословно, так как следующие выделенные части кода «просто для того, чтобы он работал»:

NestWhile[{Random[8&2]},0,{Sum@_/=_2}&_]
          ^           ^^^^^        ^^^^

И я отбросил эту идею.

Выбор интереснее. Основная концепция заключается в использовании BaseBelow[b, n]встроенной функции, которая генерирует список всех базовых bцелых чисел ширины n(в виде числовых массивов), от 0до b^n-1. Например, BaseBelow[3, 2]генерирует все троичные целые числа ширины 2:

A> BaseBelow[3, 2]
 0 0
 0 1
 0 2
 1 0
 1 1
 1 2
 2 0
 2 1
 2 2

Мы специально используем BaseBelow[2, 8]все двоичные целые числа ширины 8. Они представляют все возможные минные поля любой длины. Это первый шаг.

Вторым шагом является выбор всех таких массивов только с N1, где Nввод. Моя первая идея состояла в том, чтобы перевести это английское утверждение непосредственно в Attache:

Chunk[SortBy[Sum,BaseBelow[2,8]],Sum]@N@1

Тем не менее, он не только оказался на 1 байт длиннее, чем вышеупомянутый подход, но и очень повторяется - и даже не рандомизирован! Конечно, я мог бы сэкономить 1 байт, реорганизовавBaseBelow метод вызова, но этот подход просто не стоит использовать.

Поэтому я решил убить двух зайцев одним выстрелом и использовать Shuffleоснованный подход. Ниже приведены все допустимые минные поля длины Nв случайном порядке:

{Sum@_=_2}&N\Shuffle[BaseBelow&8!2]

Затем все, что нужно сделать, это выбрать первое. Но я могу сделать лучше - конечно, было бы лучше просто Sampleотфильтровать массив? Этот подход выглядит примерно так:

Sample[{Sum@_=_2}&_\BaseBelow[2,8]]

Мне пришлось вернуть BaseBelow&8!2гольф, потому что \приоритет слишком высок. В остальном, довольный, я продолжил отрубать байт этого:

Sample[{Sum@_=_2}&_\2&BaseBelow@8]

(Я обнаружил другой способ краткого вызова двоичной функции здесь: x&f@yэто выражение с высоким приоритетом, которое оцениваетf[x, y] .)

Однако, несмотря на это, я вспомнил , что, все вместе, псевдоним 2&BaseBelowсуществует: BinBelow. Итак, я использовал это:

Sample[{Sum@_=_2}&_\BinBelow@8]

Это создает желаемое минное поле. Я убежден, что это почти оптимально.

Часть 2: Формирование массива

Как уже говорилось ранее, техника формирования, которую я использовал, похожа на ответ J / APL, поэтому я не буду вдаваться в подробности. Предположим, MINEFIELDэто результат из последнего раздела. Функция тогда становится:

{[3,3]&Rotate[MINEFIELD'_,4]}

MINEFIELD'_объединяет минное поле с исходным вводом _, давая нам что-то вроде этого:

[1, 0, 0, 0, 1, 0, 0, 1, 3]

Затем Rotate[MINEFIELD'_,4]поверните этот список 4раз влево, поместив центр:

[1, 0, 0, 1, 3, 1, 0, 0, 0]

Последний шаг используется [3,3]&для преобразования списка в матрицу 3х3:

 1 0 0
 1 3 1
 0 0 0
Конор О'Брайен
источник
2

Java 10, 165 157 141 байт

n->{var r="___\n_"+n+"_\n___";for(int i;n>0;r=r.charAt(i*=Math.random())>58?r.substring(0*n--,i)+(i>9?0:0+r.substring(i+1)):r)i=11;return r;}

Пустые тайлы есть _(любой символ со значением Юникода выше 58 вполне подойдет) и мины есть 0.

Попробуйте онлайн.

Объяснение:

n->{                           // Method with integer parameter and String return-type
  var r="___\n_"+n+"_\n___";   //  Result-String, starting at:
                               //   "___
                               //    _n_
                               //    ___"
  for(int i;n>0                //  Loop as long as `n` isn't 0 yet:
      ;                        //    After every iteration:
       r=r.charAt(i*=Math.random())
                               //     Select a random integer in the range [0,11)
         >58?                  //     And if the character at this random index is a '_':
          r.substring(0*n--,i) //      Set `r` to the first part excluding character `i`,
                               //      (and decrease `n` by 1 in the process)
          +(i>9?0:0+           //      appended with a '0',
           r.substring(i+1))   //      appended with the second part
         :                     //     Else:
          r)                   //      Leave `r` unchanged
     i=11;                     //   Set `i` to 11 so a new random integer can be chosen
  return r;}                   //  Return the result
Кевин Круйссен
источник
1

PHP , 135 134 123 117 122 121 байт

Зацикливание на str для печати вместо этого экономит 1 байт

str_split и implode для вставки центрального номера экономит 11 байт

Больше не нужно присваивать строку $ s, сохраняя 6 байтов.
Да, вы делаете. В противном случае строка перетасовывается после каждого эха ...

Удаление пробела после эха экономит 1 байт

Замена "\ n" обычным переводом строки экономит 1 байт

$n=$argv[1];$s=implode($n,str_split(str_shuffle(str_pad(str_repeat(m,$n),8,n)),4));for(;$i<9;)echo$s[$i].(++$i%3?"":"
");

Попробуйте онлайн!

Сэм Дин
источник
1

PowerShell , 91 86 байт

-5 байт благодаря маззи

param($n)$x=,'X'*$n+,'_'*(8-$n)|random -c 8
-join$x[0..2]
$x[3,4]-join$n
-join$x[5..7]

Попробуйте онлайн!

Shuffles генерируемой строки в диапазоне от ________до XXXXXXXX(замены слева). Затем он разрезает его несколько раз, вставляя $nв середину, чтобы создать строку вывода. Эта последняя часть, вероятно, может быть значительно оптимизирована, поскольку каждый индекс стоит минимум 5 байтов.

Veskah
источник
1
хороший. 86 байт
мази
0

05AB1E , 12 байтов

$×8j.r2äIý3ô

Использует 0для шахт, пространства для пустых квадратов. Выводит список строк, который довольно распечатан в TIO ниже, соединяясь с разделителем строк ( »).

Попробуйте онлайн или проверьте еще несколько тестовых случаев одновременно .

Объяснение:

$             # Push 0 and the input-digit
 ×            # Repeat the 0 the input-digit amount of times as string
              #  i.e. 4 → "0000"
  8j          # Prepend spaces to make the size 8
              #  → "    0000"
    .r        # Randomly shuffle the characters in this string
              #  i.e. "    0000" → " 00 0  0"
      2ä      # Split it into two equal halves (of 4 characters)
              #  → [" 00 ","0  0"]
        Iý    # Join it with the input-digit
              #  → " 00 40  0"
          3ô  # And then split it into (three) parts of 3 characters
              #  → [" 00"," 40","  0"]
              # (which is output implicitly as result)

12 байтов альтернатива:

8L@.rIš5._3ô

Использует 1для шахт, 0для пустых квадратов. Выводит матрицу цифр, которая довольно печатается в TIO ниже, соединяя каждую строку, а затем эти строки с разделителем новой строки ( ).

Попробуйте онлайн или проверьте еще несколько тестовых случаев одновременно .

Объяснение:

8L            # Push the list [1,2,3,4,5,6,7,8]
  @           # Check for each if the (implicit) input-integer is >= it
              # (1 if truthy; 0 if falsey)
              #  i.e. 4 → [1,1,1,1,0,0,0,0]
   .r         # Randomly shuffle this list
              #  i.e. [1,1,1,1,0,0,0,0] → [0,1,1,0,1,0,0,1]
     Iš       # Prepend the input-digit to the list
              #  → [4,0,1,1,0,1,0,0,1]
       5._    # Rotate the list five times towards the left
              #  → [1,0,0,1,4,0,1,1,0]
          3ô  # And then split it into (three) parts of 3 digits each
              #  → [[1,0,0],[1,4,0],[1,1,0]]
              # (which is output implicitly as result)
Кевин Круйссен
источник