Знайдіть усі (анти) діагоналі з подвоєними значеннями


17

Виклик:

Давши вхід матриці, визначте кількість діагоналей та антидіагоналей із дублюючими числами.
Отже, якщо у нас є така матриця:

[[aa,ab,ac,ad,ae,af],
 [ba,bb,bc,bd,be,bf],
 [ca,cb,cc,cd,ce,cf],
 [da,db,dc,dd,de,df]]

Усі діагоналі та антидіагоналі будуть:

[[aa],[ab,ba],[ac,bb,ca],[ad,bc,cb,da],[ae,bd,cc,db],[af,be,cd,dc],[bf,ce,dd],[cf,de],[df],
 [af],[ae,bf],[ad,be,cf],[ac,bd,ce,df],[ab,bc,cd,de],[aa,bb,cc,dd],[ba,cb,dc],[ca,db],[da]]

Приклад:

[[1,2,1,2,1,2],
 [1,2,3,4,5,6],
 [6,5,4,3,2,1],
 [2,1,2,1,2,1]]

Усі діагоналі та антидіагоналі будуть:

[[1],[2,1],[1,2,6],[2,3,5,2],[1,4,4,1],[2,5,3,2],[6,2,1],[1,2],[1],
 [2],[1,6],[2,5,1],[1,4,2,1],[2,3,3,2],[1,2,4,1],[1,5,2],[6,1],[2]]

Видалення всіх діагоналей та антидіагоналей, що містять лише унікальні числа:

[[2,3,5,2],[1,4,4,1],[2,5,3,2],[1,4,2,1],[2,3,3,2],[1,2,4,1]]

Отже, вихід - це кількість діагоналей та антидіагоналей, що містять дублювані числа:

6

Правила виклику:

  • Якщо вхідна матриця порожня, містить лише 1 число або містить лише унікальні числа по всій матриці, вихід завжди є 0.
  • Введення гарантовано містить лише позитивні цифри [1,9](якщо вони повністю порожні).
  • Матриця завжди буде прямокутної (тобто всі рядки мають однакову довжину).
  • Введення / виведення гнучко. Введення можна сприймати як список списків цілих чисел, або двовимірний масив цілих чисел, або матричний об'єкт, як рядок тощо. Ви також можете прийняти один або обидва розміри матриці як додатковий вхід якщо це дозволить зберегти байти на обраній вами мові.

Загальні правила:

  • Це , тому найкоротша відповідь у байтах виграє.
    Не дозволяйте мовам коду-гольфу відштовхувати вас від публікації відповідей з мов, що не кодують гольф. Спробуйте придумати якомога коротшу відповідь на "будь-яку" мову програмування.
  • Для вашої відповіді застосовуються стандартні правила з правилами вводу / виводу за замовчуванням , тому вам дозволяється використовувати STDIN / STDOUT, функції / метод із відповідними параметрами та повним програмами типу повернення. Твій дзвінок.
  • Лазівки за замовчуванням заборонені.
  • Якщо можливо, додайте посилання з тестом для вашого коду (тобто TIO ).
  • Також настійно рекомендується додавати пояснення до своєї відповіді.

Тестові приклади:

Input:                     Output:

[[1,2,1,2,1,2],            6
 [1,2,3,4,5,6],
 [6,5,4,3,2,1],
 [2,1,2,1,2,1]]

[[]]                       0

[[1,2],                    0
 [3,4]]

[[1,1],                    2
 [1,1]]

[[9,9,9],                  6
 [9,9,9],
 [9,9,9]]

[[7,7,7,7],                8
 [7,7,7,7],
 [7,7,7,7]]

[[1,1,1],                  1
 [2,3,4],
 [2,5,1]]

[[1,8,4,2,9,4,4,4],        12
 [5,1,2,7,7,4,2,3],
 [1,4,5,2,4,2,3,8],
 [8,5,4,2,3,4,1,5]]

[[1,2,3,4],                4
 [5,6,6,7],
 [8,6,6,9],
 [8,7,6,5]]

Відповіді:



10

R , 92 86 82 78 байт

function(m,x=row(m),y=col(m),`|`=split,`^`=Map)sum(max^table^c(m|x-y,m|x+y)>1)

Спробуйте в Інтернеті!

Пояснення

xy

xy

0 -1 -2 -3 1 0 -1 -2 2 1 0 -1 3 2 1 0

x+у

2 3 4 5 3 4 5 6 4 5 6 7 5 6 7 8

Тепер split(m, x-y)і split(m, x+y)складемо фактичні списки діагоналей та антидіагоналей, які ми об’єднуємо разом.

Нарешті, ми підраховуємо записи отриманого списку, де є дублікати.

Дякуємо за збережені байти:

-4 від Кримінально-Вульгарного
вульгарний -4 - DigEmAll


1
Думаю , я можу додати rowі colв мій список «надзвичайно ситуаційних функцій». Дійсно розумне рішення.
Кримінально-

1
Я думаю, ви можете перемістити c(m|x-y,m|x+y)прямо в дзвінок під час руху, зняти l=деталь. Я не бачу жодних невдалих тестів. Спробуйте в Інтернеті!
Кримінально-

Так, це правильно, я просто пропустив, що після мого першого гольфу залишився лише один lекземпляр.
Кирило Л.

1
Вони, мабуть, сьогодні додали R rowта columnфункції до R, бо я ніколи про них не чув.
ngm

5

J , 21 20 байт

-1 байт завдяки Джуні!

1#.|.,&((~:&#~.)/.)]

Спробуйте в Інтернеті!

Пояснення:

1#.                   find the sum of the  
     ,                concatenation of
       (          )   the result of the verb in the parentheses applied to
                   ]  the input
      &               and
   |.                 the reversed input
        (      )/.    for each diagonal
         ~:&#~.       check if all elements are unique and negate the result 

1
це щось божевільне, що ти не можеш зробити краще, ніж (-.@-:~.)для "унікальних предметів, які не відповідають" в J, але я теж стикався з цим багато разів, і я не думаю, що ти можеш ... у нас є, =і ~:на одному руку, і -:і <this is missing>.
Йона

На насправді, вдалося поголити ще 1 байт від: 1#.|.,&((~:&#~.)/.)]. Спробуйте в Інтернеті!
Йона

@Jonah: класне використання &, дякую!
Гален Іванов

5

Japt , 31 байт

ËcUî
ËéEÃÕc¡XéYnÃÕ mf fÊk_eZâÃl

Спробуйте всі тестові випадки

Пояснення:

Ëc                            #Pad each row...
  Uî                          #With a number of 0s equal to the number of rows

ËéEÃÕ                         #Get the anti-diagonals:
ËéEÃ                          # Rotate each row right a number of times equal to the row's index
    Õ                         # Get the resulting columns
     c                        #Add to that...
      ¡XéYnÃÕ                 #The diagonals:
      ¡XéYnà                  # Rotate each row left a number of times equal to the row's index
            Õ                 # Get the resulting columns
              mf              #Remove the 0s from each diagonal
                 fÊ           #Remove the all-0 diagonals
                   k_   Ã     #Remove the ones where:
                     eZâ      # The list contains no duplicates
                         l    #Return the number of remaining diagonals

Я також спробував версію, засновану на відповіді Кіскеля Л. Хаскелла, але не зміг знайти хороший спосіб "згрупувати функцію за індексами X і Y", і альтернатива, яку я знайшов, була недостатньо хорошою.



4

JavaScript (ES6),  107 105 101  98 байт

f=(m,d=s=1)=>(m+0)[s-=~d/2]?m.some(o=(r,y)=>!r.every((v,x)=>x+d*y+m.length-s?1:o[v]^=1))+f(m,-d):0

Спробуйте в Інтернеті!

Примітка

Те, як цей код є полем, антидіагональ, що складається з підошви в нижній лівій клітці, ніколи не перевіряється. Це нормально, оскільки він не може містити дублюваних значень.

Прокоментував

f = (                    // f = recursive function taking:
  m,                     //   m[] = input matrix
  d =                    //   d   = direction (1 for anti-diagonal or -1 for diagonal)
  s = 1                  //   s   = expected diagonal ID, which is defined as either the sum
) =>                     //         or the difference of x and y + the length of a row
  (m + 0)[               //
    s -= ~d / 2          // increment s if d = -1 or leave it unchanged otherwise
  ] ?                    // if s is less than twice the total number of cells:
    m.some(o =           //   o = object used to store encountered values in this diagonal
    (r, y) =>            //   for each row r[] at position y in m[]:
      !r.every((v, x) => //     for each cell of value v at position x in r[]:
        x + d * y +      //       x + d * y + m.length is the ID of the diagonal
        m.length - s ?   //       if it's not equal to the one we're looking for:
          1              //         yield 1
        :                //       else:
          o[v] ^= 1      //         toggle o[v]; if it's equal to 0, v is a duplicate and
                         //         every() fails which -- in turn -- makes some() succeed
      )                  //     end of every()
    )                    //   end of some()
    + f(m, -d)           //   add the result of a recursive call in the opposite direction
  :                      // else:
    0                    //   stop recursion

4

05AB1E , 25 байт

í‚εεygÅ0«NFÁ]€ø`«ʒ0KDÙÊ}g

Спробуйте в Інтернеті! або як тестовий набір

Пояснення

í                          # reverse each row in input
 ‚                         # and pair with the input
  ε                        # for each matrix
   ε                       # for each row in the matrix
    ygÅ0«                  # append len(row) zeroes
         NFÁ               # and rotate it index(row) elements to the right
            ]              # end loops
             €ø            # transpose each matrix
               `«          # append them together
                 ʒ     }   # filter, keep only rows that
                  0K       # when zeroes are removed
                    DÙÊ    # are not equal to themselves without duplicate values                           
                        g  # push length of the result

Я відчуваю, що тут щось пропустив.
Потрібно спробувати і пограти в гольф пізніше.


1
Це зовсім не допомагає, але rotate N leftбуло б N._зараз. Так í‚εεygÅ0«N._]також працює. Можна також зняти вирівнювання за допомогою цієї нової зміни ... все ще немає байтових заощаджень, хоча:í‚vyεygÅ0«N._}ø}«ʒ0KDÙÊ}g
Чарівний восьминіг

1
@MagicOctopusUrn: Цікаво. Я пропустив цю команду. Тільки ліва, хоча. Це дивно.
Емінья

1
@Emigna Ви можете піти правильно, N(._я думаю, але ваша NFÁ}така ж довжина і ще коротша в цьому випадку через ]одночасне закриття циклу та карт. В цілому використання ._корисно лише, якщо піде ліворуч, щоб зберегти 1 байт порівняно з NFÀ}.
Kevin Cruijssen

@KevinCruijssen: Ах, здорово. Хоча, як ви кажете, не дуже корисно.
Емінья


3

Октава , 98 байт

@(A)nnz([(q=@(Q)arrayfun(@(n)nnz(z=diag(Q,n))-nnz(unique(z)),-([m,n]=size(Q)):n))(A),q(rot90(A))])

Спробуйте в Інтернеті!


1
Чи справді масиви цікаві? ; p
Кевін Круїссен

І дякую за підготовку тестових випадків у форматі Octave!
Луїс Мендо

2
@KevinCruijssen Не лише масиви! Ви можете мати cellfunі для мазохістичного structfun. У Octave це або цикл for, або мати fun!
Санчіз

І не забудьте b-sx-fun!
Луїс Мендо

3

Haskell, 118 112 байт

import Data.List
r#(a:b)=sum[1|(/=)=<<nub$[h|h:_<-a:r]]+[t|_:t<-a:r]#b
[]#_=0
a#_=a#[[]]
h x=[]#x+[]#(reverse x)

Спробуйте в Інтернеті!

r#(a:b)                      -- function '#' calculates the ant-diagonals of a matrix
                             -- where 'a' is the first row and 'b' all the others
                             -- as we recursively walk down the rows of the matrix,
                             -- 'r' holds the rows from before with the respective
                             -- head dropped
                             --
          [h|h:_<-a:r]       -- if the heads of the the current row and the rows
                             -- before
       (/=)=<<nub$           -- contain duplicates
    [1|                ]     -- make a singleton list [1] (else the empty list)
 sum                         -- and take the sum thereof
      +                      -- and add
             #               -- a recursive call with
 [t|_:t<-a:r]                -- the tails of the current row and the rows before
              b              -- and the rows below
                             --
[]#_=0                       -- base case if there aren't any tails anymore, return 0
a#_=a#[[]]                   -- if there are tails, but no further rows below,
                             -- continue with tails

h x=[]#x+[]#(reverse x)      -- main function, call '#' with input matrix 'x'
                             -- and the reverse of it to get the number of diagonals
                             -- and anti-diagonals. Recursion starts with no
                             -- rows before the 1st row.

-- example trace of function '#'
-- input matrix:
--   [[1,2,3,4],
--    [5,6,7,8],
--    [9,9,9,9]]
--
--  | r         a          b              a:r          heads   tails (r of next call)
-- -+----------------------------------------------------------------------------------
-- 1| []        [1,2,3,4]  [[5,6,7,8],    [[1,2,3,4]]  [1]     [[2,3,4]]
--  |                       [9,9,9,9]]
--  | 
-- 2| [[2,3,4]]  [5,6,7,8]  [[9,9,9,9]]   [[5,6,7,8],  [5,2]   [[6,7,8],
--  |                                      [2,3,4  ]]           [3,4  ]]
--  |
-- 3| [[6,7,8],  [9,9,9,9]  []            [[9,9,9,9],  [9,6,3] [[9,9,9],
--  |  [3,4  ]]                            [6,7,8  ],           [7,8  ]
--  |                                      [3,4    ],           [4    ]
--  |
--  | ....

2

Вугілля деревне , 61 56 53 байт

F²FLθFL§θ⁰F⟦⁻κ×⊖⊗ιλ⟧⊞υ⊞O⎇∧λ﹪⁺μιLθ⊟υ⟦⟧§§θμλILΦυ⊙ι‹⌕ιλμ

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

F²

Петля вперед і назад по діагоналях; i=0представляє діагоналі вперед, в той час як i=1реверсивні діагоналі.

FLθ

Переведіть петлю на кожен індекс рядка. Це являє собою індекс початку діагоналі.

FL§θ⁰«

Переведіть петлю на кожен індекс стовпця.

F⟦⁻κ×⊖⊗ιλ⟧

Обчисліть індекс рядків діагоналі за цим індексом стовпця. Я використовую forцикл над одноелементним масивом замість призначення, оскільки це дозволяє уникнути необхідності загортати призначення у блок із наступним висловом, зберігаючи таким чином байт.

⎇∧λ﹪⁺μιLθ

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

⊟υ

Якщо це не так, виберіть останній список зі списку списків.

⟦⟧

якщо це, то запустіть новий порожній список.

⊞O...§§θμλ

Додайте поточний діагональний запис до цього списку.

⊞υ

І натисніть цей список (назад) до списку списків.

ILΦυ⊙ι‹⌕ιλμ

Порахуйте кількість списків, що містять дублікати.

Візьмемо приклад, коли i=0і k=1. Це означає , що ми вже зібрали два діагоналей, [[1,1,5,2],[9,4,3,5]]. Ось наш внесок:

 1 8 4 2 9 4 4 4
[5]1 2 7 7 4 2 3
 1 4 5 2 4 2 3 8
 8 5 4 2 3 4 1 5

Потім ми петлю lвід 0до 7. Це переміщує обидва рядки та стовпці на 1:

 1 8 4 2 9 4 4 4
[5]1 2 7 7 4 2 3
 1[4]5 2 4 2 3 8
 8 5[4]2 3 4 1 5

Список зараз [[1,1,5,2],[9,4,3,5],[5,4,4]]. Однак , коли lє 3, у нас є k+l=4, кратна висота масиву. Це означає , що ми повинні почати новий список: [[1,1,5,2],[9,4,3,5],[5,4,4],[]]. Потім ми продовжуємо збирати діагональні елементи:

 1 8 4[2]9 4 4 4
[5]1 2 7[7]4 2 3
 1[4]5 2 4[2]3 8
 8 5[4]2 3 4[1]5

Список зараз [[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1]]. Тепер , коли lє 7, у нас є k+l=8, ще кратно висоті масиву. Це означає , що ми повинні почати новий список, який закінчується з останнім елементом , який по діагоналі: [[1,1,5,2],[9,4,3,5],[5,4,4],[2,7,2,1],[4]].

 1 8 4[2]9 4 4[4]
[5]1 2 7[7]4 2 3
 1[4]5 2 4[2]3 8
 8 5[4]2 3 4[1]5

Збираючи обгорткові діагоналі, починаючи з першого елемента кожного ряду, ми з часом накопичуємо всі діагоналі масиву.



1

APL + WIN, 69 байт

Підказки до 2d матриці форми 4 6⍴1 2 1 2 1 2 1 2 3 4 5 6 6 5 4 3 2 1 2 1 2 1 2 1

Це дає:

1 2 1 2 1 2
1 2 3 4 5 6
6 5 4 3 2 1
2 1 2 1 2 1

+/~(v⍳¨v)≡¨⍳¨⍴¨v←(v←⊂[1](⌽0,⍳1↓n)⌽(n⍴0),m,((n←0 ¯1+↑⍴m)⍴0),⌽m←⎕)~¨0

Спробуйте в Інтернеті! Надано Dyalog Classic

Пояснення:

(⌽0,⍳1↓n)⌽(n⍴0),m pad m with zeros to isolate diagonals

((n←0 ¯1+↑⍴m)⍴0),⌽m pad rotated m with zeros to isolate anti-diagonals

Врожайність:

1 2 1 2 1 2 0 0 0 2 1 2 1 2 1 0 0 0
0 1 2 3 4 5 6 0 0 0 6 5 4 3 2 1 0 0
0 0 6 5 4 3 2 1 0 0 0 1 2 3 4 5 6 0
0 0 0 2 1 2 1 2 1 0 0 0 1 2 1 2 1 2

v←(v←⊂[1](.....)~¨0 enclose the diagonals as a nested vector with padded zeros removed

+/~(v⍳¨v)≡¨⍳¨⍴¨v identify diagnols with duplicate entries and sum


1

TSQL, 140 128 байт

Знайшов шлях до гольфу 12 символів. Це вже не найдовше рішення.

Гольф:

SELECT sum(iif(y+x=j+i,1,0)+iif(y-x=j-i,1,0))FROM
@,(SELECT x i,y j,max(y)over()m,v w
FROM @)d WHERE(x*y=0or m=y)and v=w and x<i

Безголівки:

DECLARE @ table(v int,x int,y int)
-- v = value
-- x = row 
-- y = column
INSERT @ values
(1,0,0),(2,0,1),(1,0,2),(2,0,3),(1,0,4),(2,0,5),
(1,1,0),(2,1,1),(3,1,2),(4,1,3),(5,1,4),(6,1,5),
(6,2,0),(5,2,1),(4,2,2),(3,2,3),(2,2,4),(1,2,5),
(2,3,0),(1,3,1),(2,3,2),(1,3,3),(2,3,4),(1,3,5)


SELECT sum(iif(y+x=j+i,1,0)+iif(y-x=j-i,1,0))
FROM @,(SELECT x i,y j,max(y)over()m,v w FROM @)d
WHERE
  (x*y=0or m=y)
  and v=w
  and x<i

Спробуй

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.