Modfalten erkennen

18

Aufgabe

Definieren Sie eine Modfalte als Funktion der Form f (x) = x% a 1  % a 2  %…% a k , wobei a i positive ganze Zahlen und k ≥ 0 sind . (Hier ist % der linksassoziative Modulo-Operator.)

Bestimmen Sie anhand einer Liste von n ganzen Zahlen y 0 ,…, y n - 1 , ob es eine Modfalte f gibt, so dass jedes y i  = f (i) .

Sie können zwei beliebige Ausgänge Y und N für Ihre Funktion / Ihr Programm auswählen und festlegen . Wenn es ein solches f gibt , müssen Sie immer genau Y zurückgeben / drucken ; Wenn nicht, müssen Sie immer genau N zurücksenden / ausdrucken . (Dies können true/ false, oder 1/ 0, oder false/ trueusw. sein.) Erwähnen Sie diese in Ihrer Antwort.

Die kürzeste Übermittlung in Bytes gewinnt.

Beispiel

Definiere f (x) = x% 7% 3 . Seine Werte beginnen:

|   x  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ...
| f(x) | 0 | 1 | 2 | 0 | 1 | 2 | 0 | 0 | 1 | 2 | ...

Somit gegeben 0 1 2 0 1 2 0 0 1 2als Eingabe für unsere Lösung, würden wir drucken Y , wie dies f diese Sequenz erzeugt. Als 0 1 0 1 2Eingabe würden wir jedoch N ausgeben , da kein f diese Sequenz erzeugt.

Testfälle

Die bei der Ausgabe von Y angegebenen Formeln dienen nur als Referenz. Sie dürfen sie zu keinem Zeitpunkt ausdrucken.

0 1 2 3 4 5              Y    (x)
1                        N
0 0 0                    Y    (x%1)
0 1 2 0 1 2 0 0 1 2      Y    (x%7%3)
0 0 1                    N
0 1 2 3 4 5 6 0 0 1 2    Y    (x%8%7)
0 1 2 0 1 2 0 1 2 3      N
0 2 1 0 2 1 0 2 1        N
0 1 0 0 0 1 0 0 0 0 1    Y    (x%9%4%3%2)
Lynn
quelle
Gibt es Zeit- oder Speicherbeschränkungen?
Dennis
2
Kann ich stattdessen Wahrheitswerte und falsche Werte ausgeben?
Undichte Nonne
2
@Leaky Ich würde dich lieber nicht. Ich bin kein großer Fan von Wahrheitsliebe. Ich versuche dies ausdrücklich als eine objektivere Alternative, die Ihnen immer noch Freiheit gibt.
Lynn
@Lynn bin es nur ich oder du hast es immer noch nicht behoben?
Undichte Nonne
In Bezug auf Speicher- / Zeitbeschränkungen: Ich glaube nicht, dass ich der Herausforderung selbst etwas hinzufügen werde, aber ich könnte eine Prämie für die kürzeste Antwort in Bytes auslösen, die jeden meiner Testfälle in einer angemessenen Zeitspanne beantworten kann.
Lynn

Antworten:

7

Pyth, 14 Bytes

}Qm%M+RdUQy_Sl

Rückgabe True/False. Probieren Sie es online aus: Demo oder Test Suite

Erläuterung:

}Qm%M+RdUQy_SlQ   implicit Q (=input) at the end
             lQ   length of input list
            S     create the list [1, 2, ..., len]
           _      reverse => [len, ..., 2, 1]
          y       generate all subsets (these are all possible mod-folds)
  m               map each subset d to:
        UQ           take the range [0, 1, ..., len-1]
     +Rd             transform each number into a list by prepending it to d
                     e.g. if mod-fold = [7,3], than it creates:
                        [[0,7,3], [1,7,3], [2,7,3], [3,7,3], ...]
   %M                fold each list by the modulo operator
                  this gives all possible truthy sequences of length len
}Q                so checking if Q appears in the list returns True or False

Pyth, 11 Bytes

q%M.e+k_tx0

Basierend auf der Idee von @ ferrsum . Ich habe tatsächlich darüber nachgedacht, die Nullindizes für die Teilmengengenerierung zu verwenden, aber nicht erkannt, dass alle Nullindizes bereits die Lösung sein müssen.

Jakube
quelle
4

Python 3, 239 218 Bytes

from itertools import*
lambda z:z in[[eval(''.join([str(l)]+['%'+str(i[::-1][k])for k in range(len(i))]))for l in range(len(z))]for i in(i for j in(combinations(range(1,len(z)+1),i+1)for i in range(len(z)))for i in j)]

Eine anonyme Funktion, die eine Liste zeingibt und Trueoder Falsefür Yund zurückgibt N.

Hierbei wird eine Methode verwendet, die der Antwort von @Jakube ähnelt , und obwohl es sich im Wesentlichen um eine rohe Kraft handelt, wird sie sehr schnell ausgeführt.

from itertools import*               Import everything from the Python module for
                                     iterable generation
lambda z                             Anonymous function with input list z
combinations(range(1,len(z)+1),i+1)  Yield all sorted i+1 length subsets of the range
                                     [1,len(z)]...
...for i in range(len(z))            ...for all possible subset lengths
(i for j in(...)for i in j)          Flatten, yielding an iterator containing all possible
                                     mod-fold values as separate lists
...for i in...                       For all possible mod-fold values...
...for k in range(len(i))            ...for all mod-fold values indices k...
...for l in range(len(z))            ...for all function domain values in [0,len(z)-1]...
[str(l)]+['%'+str(i[::-1][k])...]    ...create a list containing each character of the
                                     expression representing the function defined by the
                                     mod-fold values (reversed such that the divisors
                                     decrease in magnitude) applied to the domain value...
 eval(''.join(...))                  ...concatenate to string and evaluate...
 [...]                               ...and pack all the values for that particular
                                     function as a list
 [...]                               Pack all lists representing all functions into a list
 ...:z in...                         If z is in this list, it must be a valid mod-fold, so
                                     return True. Else, return False

Probieren Sie es auf Ideone

TheBikingViking
quelle
4

Python 2, 69 Bytes

f=lambda a,i=0:i/len(a)or a[i]in[a[i-1]+1,i,0][i<=max(a)::2]*f(a,i+1)

Verwendet True/ False.

Die Antwort auf das, was eine Mod-Foldable-Serie auszeichnet, ist weniger interessant, als es zunächst scheint. Es ist eine Reihe der Form 0, 1, ..., M - 1, 0, 1, ... x 1 , 0, 1, ..., x 2 , ..., so dass für alle i, 0 <= x i <M. Eine solche Sequenz kann durch die Mod-Kette aller (0-basierten) Indizes der Nullen im Array mit Ausnahme des ersten erzeugt werden.

Feersum
quelle
3

Jelly , 19 15 14 Bytes

LṗLUZ’1¦%/sLe@

Gibt 1 für wahr, 0 für falsch zurück. Probieren Sie es online!

Der Algorithmus ist O (n n ) , wobei n die Länge der Liste ist, was sie für die meisten Testfälle zu langsam und speicherintensiv macht.

Mit einer geänderten Version, die die zweite Ldurch eine ersetzt, 5können alle Testfälle überprüft werden . Beachten Sie, dass diese modifizierte Version für beliebig lange Listen nicht funktioniert.

Wie es funktioniert

LṗLUZ’1¦%/sLe@  Main link. Argument: A (array of integers)

L L             Yield the length l of A.
 ṗ              Take the l-th Cartesian power of [1, ..., l], i.e., construct
                all arrays of length l that consist of elements of [1, ..., l].
   U            Upend/reverse each array. This way, the first l arrays start
                with [1, ..., l], as do the next l arrays, etc.
    Z           Zip/transpose the array of arrays.
     ’1¦        Decrement the first array to map [1, ..., l] to [0, ..., l - 1].
        %/      Reduce the array's columns by modulus/residue.
          sL    Split the result into chunks of length l.
            e@  Verify if A belongs to the resulting array.
Dennis
quelle
Können Sie eine Erklärung hinzufügen? Als jemand, der Jelly (noch) nicht verwendet hat, habe ich keine Ahnung, wie es funktioniert.
Steven H.
Ich werde eine hinzufügen, sobald ich mit dem Golfen fertig bin. Es gibt noch ein paar Dinge, die ich zuerst ausprobieren möchte.
Dennis
Ich habe (aufgegeben und) eine Erklärung hinzugefügt.
Dennis
3

JavaScript (ES6), 98 Byte

a=>a.every((n,i)=>n?n<(l+=p==i)&&n==p++:p=1,l=p=1)

48 Bytes gespart, indem zu @ Feersums Entdeckung gewechselt wurde. Jeder gegebene Wert nin dem Array ist entweder Null, in welchem ​​Fall die nächste Vorhersage p1 ist, oder er ist gleich der nächsten Vorhersage, in welchem ​​Fall pinkrementiert wird. Wir messen auch die Länge lder Anfangssequenz durch Vergleichen pmit i, da sie nimmer kürzer als lzu allen Zeiten sein muss.

Neil
quelle
2

Python 2, 103 99 Bytes

f=lambda l,r:r==x or l and f(l-1,[t%l for t in r])|f(l-1,r)
x=input();l=len(x);print+f(l,range(l))

Druck 1 für truthy und 0 für falsy. Teste es auf Ideone .

Dennis
quelle