Паліндромні основні фактори


15

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

Завдання

Ваш код повинен приймати як вхідне одне ціле число. Потім перевірте, чи будь-яка перестановка простих факторів цього цілого числа є паліндромною при конкатенації. Якщо так, виведіть один із них (список факторів, а не з'єднаний рядок). Інше, ви повинні вивести -1.

Це , тому найкоротший код у байтах виграє!

Випробування

11 -> [11]
4 -> [2, 2]
39 -> [3, 13]
6 -> -1
1207 -> [17, 71]
393 -> -1
2352 -> [2, 2, 7, 3, 7, 2, 2]

1
Чи можуть відрізнятися інші значення, ніж -1 повертаються? У Perl 6 Я думаю про те Nil, Failчи інші невизначені значення. Також може бути результатом будь-яке позиційне значення?
Бред Гілберт b2gills

Список, масив, послідовність, діапазон, Buf, ковзання - усі позиційні значення. Саме вони виконують Позиційну роль.
Бред Гілберт b2gills

Отже .. чи слід виводити порожній список для 1, або -1?
Джо Кінг

-1 як елемент відрізняється від одного масиву, який містить лише -1
RosLuP

Відповіді:



3

Піт, 14 байт

-2 байти від @FryAmTheEggman

h+f_IjkT.pPQ_1

Пояснення:

h                 first element of
 +                (append a -1 to the end in case the filter is empty)
  f                 filter by lambda T:
   _I                 is invariant under reversing
     jkT              stringified list
   .p                over permutations of
     P Q             prime factors of Q with duplicates
  _1              -1

Дякую @FryAmTheEggman за те, що нагадав про мене I. Я не думаю, що я цим раніше користувався.

Тестовий набір


jkте саме, щоs`M
Мальтісен

3

CJam - 17 байт

Дякую Мартіну Бюттнеру, що врятував мені 10 байт!

Wqimfe!{s_W%=}=p;

Перший раз писав у CJam! Пояснення:

W              # Push a -1 onto the stack
q               # Get input
i               # Convert to integer
mf              # Find prime factorization
e!              # Find all permutations
{...}=          # Find permutation which...
s               # Convert to string
_               # Copy string
W%              # Get inverse
=               # Check if inverse == original
p;              # Print top of stack and discard the rest

3
Ви можете змінити рядок (або масив) за допомогою W%. Ви також можете використовувати =з блоком, щоб отримати першу паліндромну основну факторизацію. Це складає 18 байт: Wrimfe!{s_W%=}=p];... ви можете зберегти ще один, припинивши помилку (оскільки вихід помилки переходить до STDERR):Wrimfe!{s_W%=}=p;
Мартін Ендер

3
@ MartinBüttner Ось чому я люблю PPCG. Всі такі корисні та доброзичливі!
KoreanwGlasses

2

Рубі, 89 + 7 = 96 102 + 7 = 109

->n{n.prime_division.flat_map{|*a,b|a*b}.permutation.find{|x|x.join==x.join.reverse}||-1}

+7 для -rprime прапора.

Зітхнути , деякі побудовані Ruby мають такі довгі назви ... принаймні, це робить код досить зрозумілим.

flat_mapБіт , тому що prime_divisionповертається отл. [[2, 2], [3, 1]]для введення 12(що представляє2231 ).

Дякуємо @histocrat за 13 байт!


@histocrat Це була помилка з боку ОП (див. коментарі до питання). Дякую, це акуратний трюк із шльопцем.
Дверна ручка

2

Джулія, 132 122 байти

n->(x=filter(p->(q=join(p))==reverse(q),permutations(foldl(vcat,[[repeated(k,v)...]for(k,v)=factor(n)]))))==[]?-1:first(x)

Це лямбда-функція, яка приймає ціле число і повертає або масив, або -1. Щоб викликати його, призначте його змінній.

Безголівки:

function f(n::Int)
    # Construct an array of all prime factors of n
    P = foldl(vcat, [[repeated(k, v)...] for (k, v) in factor(n)])

    # Filter the set of permutations of this array to only
    # those such that the string constructed by concatenating
    # all elements is a palindrome
    x = filter(p -> (q = join(p)) == reverse(q), P)

    # If x is empty, return -1, otherwise get the first array
    # in the collection
    return x == [] ? -1 : first(x)
end

Збережено 10 байт завдяки Glen O!


З першого погляду я бачу декілька способів покращити це (лише на основі базового гольфу). Використовуйте, foldlа не reduce(вони роблять те саме, але foldlмають визначений порядок і на один байт коротший). Використовуйте замість прямого порівняння з порожньою структуроюisempty (я не на 100% впевнений, що це за тип x, але якщо це, наприклад, використання x==[]). І використовуйте, (q=join(p))а потім просто qу фільтр, щоб зберегти ще два байти.
Глен О

Також я можу помилитися, але якщо x це масив, то, а не first(x)просто використовувати x[].
Глен О

@GlenO Дякую як завжди! Я спочатку намагався, ==[]і це давала мені помилки, але я знову спробував зараз, і це працює. Я, мабуть, щось переплутав раніше. ¯ \ _ (ツ) _ / ¯ Єдина пропозиція, яку я не міг використати, - це позбавлення first; в цьому випадку я повинен використовувати, firstтому що xце ітератор / колекція / те, що не getindexвизначено.
Олексій А.

2

Брахілог , 10 байт

ḋp.cX↔X∨_1

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

  .           The output is
 p            a permutation of
ḋ             the prime factorization of
              the input
   c          such that concatenated
    X         it is the variable X
     ↔        which reversed
      X       is still X;
       ∨      if this is not possible,
              the output is
        _1    -1.

Спочатку я очікував, що необхідність виведення, -1а не дозволу до відмови, буде досить великою вартістю байтів, але оскільки результат у випадку успіху не може бути об'єднаним, це коштує лише двох байтів, необхідних для запису _1(якщо ми видалили їх, це залишило б результат необмеженим за замовчуванням 0, а якщо ми додатково змінили на , предикат замість цього не вдасться), тому що нам потрібно розірвати об'єднання з неявним результатом. (Якщо конкатенація була результатом для успіху, але -1все-таки була результатом для відмови, у нас був би ḋpc.↔|∧_1або ḋpc.↔.∨_1. У найкоротшому випадку, коли вихід є об'єднаним і присудок може вийти з ладу, вся справа усього п'ять байтів:ḋpc.↔. Хоча невиведення фактичних факторів дає більше відчуття з ...)


1

Haskell, 122 байти

import Data.Numbers.Primes
import Data.List
f x=head$[p|p<-permutations$primeFactors x,s<-[show=<<p],s==reverse s]++[[-1]]

Приклад використання: f 39-> [3,13].

Очевидний підхід грубої сили. Ітерація над усіма перестановками основних факторів і перевірка наявності паліндром. Виберіть перший. Якщо такої немає, список порожній, а доданий додається [-1].


1

Perl 6 , 100 байт

{$/=$_;map(->\f{|({$/%f||($//=f)&&f}...^*!==f)},2..$_).permutations.first({.join.flip eq.join})||-1}
{
  # store copy of argument in $/
  $/ = $_;
  # uses $/ so that I don't have to declare a variable

  # find the prime factors
  map(
    ->\f{
      # Slip so that outer list of all prime factors is flat
      |(
        {
          $/ % f    # return modulus
          ||        # or
          ($/ /= f) # factor the prime out of $/
          &&        # and
          f         # return factor
        }
        # produce a list of them and
        # stop when it returns something other than the factor
        # also ignoring the last non-factor value
        ...^ * !== f
      )
    },
    # find the factors out of the values from 2
    # up to the original argument
    2..$_
    # don't need to skip the non-primes as their
    # prime factorization will have already be
    # factored out of $/
  )

  # try all permutations of the prime factors
  .permutations

  # find the first palindromic one
  .first({ .join.flip eq .join })

  # return -1 if .first returned Nil or empty list
  || -1
}

Використання:

# give it a lexical name
my &prime-palindrome = {...}

say prime-palindrome    1; # -1
say prime-palindrome    2; # (2)
say prime-palindrome   11; # (11)
say prime-palindrome   13; # -1
say prime-palindrome   39; # (3 13)
say prime-palindrome   93; # (31 3)
say prime-palindrome    6; # -1
say prime-palindrome 1207; # (17 71)
say prime-palindrome  393; # -1
say prime-palindrome 2352; # (2 2 7 3 7 2 2)
say prime-palindrome 2351; # -1
say prime-palindrome 2350; # -1

Близько половини (53 байти) займає основний код факторизації.

$/=$_;map(->\f{|({$/%f||($//=f)&&f}...^*!= f)},2..$_)

Якби був prime-factorizeметод, все це могло б бути значно коротшим.

{.prime-factorize.permutations.first({.join.flip eq.join})||-1} # 63

Коротший розділ основного коду може бути$!=$_;({+$!/($!/=1+(2...$!%%*))}...{2>$!})
Джо Кінг,

1

Желе , 16 байт

ÆFŒṙŒ!VŒḂ$ƇḢ¹-¹?

Довше, ніж я очікував, як у кількості байтів, так і часу, необхідного для написання.

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

Пояснення:

ÆFŒṙŒ!VŒḂ$ƇḢ¹-¹?
ÆFŒṙ                Get the prime factors (gets them as exponents then run-length decodes).
    Œ!              Get the permutations.
          Ƈ         Filter (keep) the ones that...
       ŒḂ$          ...are palindromic when...
      V             ...joined.
           Ḣ        Take the first.
              ¹?    If the value is truthy...
            ¹       ...return the value...
             -      else return -1.

1

Japt -F-1 , 9 байт

k á æ_¬êS

Спробуй це


У цьому вікні телефону у вас посилання не в порядку ...
RosLuP

@RosLuP Перекладач все ще досить новий. Я підкажу Шеггі, творця. Ось посилання TIO
Олівер

1
@RosLuP, який браузер ти використовуєш?
Кошлатий

Internet Explorer для Windows Phone 8.1: (мобільний телефон) щось зникає, можливо, краще я використовую свій новий телефон Android або браузер Windows 10 (Край, схоже, вони дзвонять)
RosLuP

0

Japt, 18 байт

Майже такий короткий, як CJam ...

Uk á f_¬¥Z¬w} g ªJ

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

Як це працює

        // Implicit: U = input, e.g. 2352
Uk      // Factorize the input.      [2,2,2,2,3,7,7]
á       // Take permutations.        [[2,2,2,2,3,7,7],[2,2,2,2,7,3,7],[2,2,2,7,2,3,7],...]
f_   }  // Filter to only the ones that return truthily to this function:
Z¬¥Z¬w  //  Return Z.join('') == Z.join('').reverse().
        //                           [[2,2,7,3,7,2,2],[2,7,2,3,2,7,2],[7,2,2,3,2,2,7]]
g       // Take the first item.      [2,2,7,3,7,2,2]
ªJ      // If falsy, resort to -1.   [2,2,7,3,7,2,2]

0

JavaScript (ES6), 256 244 208 187 байт

Збережено 36 байт завдяки @Neil

x=>eval("for(a=[],i=2;x>1;x%i?i++:(a.push(i),x/=i));p=-1,f=(z,t=[])=>z[0]?z.map((u,i)=>f([...z.slice(0,i),...z.slice(i+1)],[...t,u])):(y=t.join``)==[...y].reverse().join``&&(p=t),f(a),p")

Визначає анонімну функцію; наприклад, F=використовувати його. Насправді це досить швидко на вході 2352, і на моєму комп'ютері знадобиться лише 150 мілісекунд.


Я не знаю про швидше, але, безумовно, коротше:x=>eval("for(a=[],i=2;x>1;x%i?i++:(a.push(i),x/=i));p=[],f=(z,t=[])=>z.length?z.map((u,i)=>f([...z.slice(0,i),...z.slice(i+1)],[...t,u])):(y=t.join``)==[...y].reverse().join``&&p.push(t),f(a),p[0]||-1")
Ніл

@Neil Дякую, що також трапляється в кілька разів швидше, ніж мій алгоритм!
ETHproductions

36 байт? Я думаю, що це має бути рекордом для мене.
Ніл

0

APL (NARS), 169 символів, 338 байт

∇r←F w;i;k;a;m;j
  r←⊂,w⋄→0×⍳1≥k←↑⍴w⋄a←⍳k⋄j←i←1⋄r←⍬⋄→C
A: m←i⊃w⋄→B×⍳(i≠1)∧j=m⋄r←r,m,¨∇w[a∼i]⋄j←m
B: i+←1
C: →A×⍳i≤k
∇
G←{F⍵[⍋⍵]}
f←{∨/k←{⍵≡⌽⍵}¨∊¨⍕¨¨v←Gπ⍵:↑k/v⋄¯1}

G буде функцією знайти перестановки, а f - функцією цієї вправи; тест:

  ⎕fmt f¨11 4 39 6 1207 393 2352 
┌7───────────────────────────────────────────────────┐
│┌1──┐ ┌2───┐ ┌2────┐    ┌2─────┐    ┌7─────────────┐│
││ 11│ │ 2 2│ │ 3 13│ ¯1 │ 17 71│ ¯1 │ 2 2 7 3 7 2 2││
│└~──┘ └~───┘ └~────┘ ~~ └~─────┘ ~~ └~─────────────┘2
└∊───────────────────────────────────────────────────┘
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.