9-stelliges Problem

8

Schreiben Sie ein Programm, um eine aus 9 Ziffern bestehende Zahl zu finden, in der jede der Ziffern von 1 bis 9 nur einmal vorkommt. Diese Nummer muss auch diese Teilbarkeitsanforderungen erfüllen:

  1. Die Zahl sollte durch 9 teilbar sein.
  2. Wenn die am weitesten rechts stehende Ziffer entfernt wird, sollte die verbleibende Zahl durch 8 teilbar sein.
  3. Wenn die am weitesten rechts stehende Ziffer der neuen Nummer entfernt wird, sollte die verbleibende Nummer durch 7 teilbar sein.
  4. Und so weiter, bis es nur noch eine Ziffer gibt (die notwendigerweise durch 1 teilbar ist).

Kredit Dávid Németh

Noelkd
quelle
28
Die erste Regel erscheint unnötig. Jede Zahl, die aus den Ziffern 1-9 besteht, ist immer durch 9 teilbar.
Geobits
6
Was ist der Code-Aspekt hier? Das klingt wie es könnte auf Puzzling
Simon Forsberg
11
Selbst wenn wir es als „Standardlücke“ bezeichnen, sind Code-Golf-Herausforderungen, die eine feste Ausgabe erzeugen, die im Allgemeinen kürzer ist als jeder Code, der sie erstellen könnte, normalerweise nicht besonders interessant.
Ry
9
Das Problem, das ich bei solchen Herausforderungen habe, ist, dass die Grenze zwischen Hardcodierung und Anwendung mathematischer Eigenschaften vage ist. Die Teilbarkeitsregel für 5 lautet beispielsweise, dass die Zahl mit 0 oder 5 enden muss. Beschränkt die Auswahl für diese Ziffer auf 0 und 5, um einen Teil der Ausgabe fest zu codieren? Es würde noch schlimmer werden, wenn wir es mit 10-stelligen Zahlen zu tun hätten.
user2357112 unterstützt Monica
4
@ Sylwester Was Sie getan haben, ist anzunehmen, dass es nur einen Weg gibt, das Problem zu lösen, weil Sie Angst haben, die Lücke zu schließen. "Durchlaufen der Anforderungen zur Überprüfung von Nummern". Dies schließt alle interessanten Beispiele vollständig aus. Und die Frage ist: "Welche Sprache kann diese Dinge überprüfen und die wenigsten Zeichen einschließen".
Cruncher

Antworten:

9

CJam - 26

1{;9,:)_mrs0@{_3$<i\%+}/}g

Es ist zufällig, funktioniert aber ziemlich schnell mit dem Java-Interpreter . Mit dem Online-Dolmetscher kann es einige Minuten dauern .

Erläuterung:

1Push 1 (wird später erklärt)
{…}gist eine Do-While-Schleife,
;die einen Wert aus dem Stapel entfernt (anfangs die 1, mit der wir begonnen haben).
9,Das Array [0 ... 8]
:)erhöht die Array-Elemente, was zu [1 ... 9]
_dupliziert das Array,
mrmischt das Array
sin String-
0@Pushs 0 und bringt dann die andere Kopie des Arrays nach oben.
{…}/Für jede Schleife (über die Zahlen 1 ... 9) wird
_die aktuelle Nummer dupliziert (nennen wir es "k"). )
3$kopiert die numerische Zeichenfolge vom Stapel,
<ierhält die Teilzeichenfolge mit den ersten k Zeichen und konvertiert sie dann in ganzzahlige
\%Swaps mit der anderen Kopie von k. Anschließend erhält der Rest (% k)
+den Rest zum vorherigen Wert auf dem Stapel (anfänglich 0 von oben) )
Zu diesem Zeitpunkt haben wir die numerische Zeichenfolge auf dem Stapel, gefolgt von einer 0, wenn die Zahl allen Anforderungen entspricht (dh alle verbleibenden waren 0), oder andernfalls einem Wert ungleich 0.
Die Oberseite des Stapels wird zur Do-While-Schleifenbedingung. Es wird geknallt und die Schleife wird fortgesetzt, wenn die Bedingung erfüllt ist.
Wenn wir die Lösung gefunden haben, ist die Bedingung 0 (falsch), die Schleife endet und der Rest des Stapels (die numerische Zeichenfolge) wird gedruckt.
Wenn dies nicht die Lösung ist, ist die Bedingung der Wert ungleich 0 (true) und die Schleife wird mit der Zeichenfolge auf dem Stapel fortgesetzt. Die Zeichenfolge wird zu Beginn der nächsten Iteration gelöscht (die Schleife erwartet also einen Wert auf dem Stapel, und das ist der Grund für die anfängliche 1).

Vielen Dank an Dennis, dass er den Code kürzer und komplizierter gemacht hat: p

Aditsu beenden, weil SE böse ist
quelle
Nett! Sie können ein weiteres Byte speichern, indem Sie einen Dummy-Wert verwenden:0{;9,:)_mrsT@{_3$<i\%+}/}g
Dennis
7

Javascript (E6) 105 125 134

Rekursives Erstellen der Zahl, jeder Schritt prüft die Teilbarkeit.
Laufzeit nahe 0 Sek.
Diesmal keine E / A, da das OP nach einem Programm gefragt hat, um die Nummer zu finden, und die Nummer gefunden und automatisch an der Konsole protokolliert wird

Mehr Golf mit freundlicher Genehmigung von MT0

(Q=(n,d,b)=>([(m=n+(s=[...b]).splice(i,1))%d||Q(m,d+1,s)for(i in b)],d>9&&(Q.z=n),Q.z))('',1,'123456789')

Golf gespielt

(Q=(n='',d=1,b=[...'123456789'],i)=>{
for(i=0;s=[...b],m=n+s.splice(i,1),b[i];i++)m%d||Q(m,d+1,s);d>9&&(Q.z=n);return Q.z;
})()

Hässlich

(Q=(n='', d=1, b=[...'123456789'], i) => {
   for(i=0; s=[...b], m=n+s.splice(i,1), b[i]; i++)
     m % d || Q(m,d+1,s);
   d > 9 && (Q.z=n);
   return Q.z;
})()

Bonus

Mit 3 kleinen Änderungen können Sie dieselbe Funktion verwenden, um längere Zahlen mit base> 10 zu finden. Zum Beispiel in base 14 ...

(Q=(n='',d=1,b=[...'123456789ABCD'],i)=>{
  for(i=0; s=[...b], m = n+s.splice(i,1), b[i]; i++)
    parseInt(m,14)%d || Q(m,d+1,s);
  d>13 && (Q.z=n);
  return Q.z;
})()

9C3A5476B812D

Ungolfed

Q=(n,d,b,i,c,z)=>{ // i,c,z fake parameters instead of vars.
  for (i=0; b[i]; i++)
  {
    s=[...b];
    m = n + s.splice(i,1);
    if (m % d == 0)
      if (z = d<9 ? Q(m, d+1, s) : m) return z;
  }
}
Q('',1,[...'123456789'])
edc65
quelle
1
105 Zeichen:(Q=(n,d,b)=>([(m=n+(s=[...b]).splice(i,1))%d||Q(m,d+1,s)for(i in b)],d>9&&(Q.z=n),Q.z))('',1,'123456789')
MT0
101 Charaktere:(Q=(n,d,b)=>Math.max(...[(m=n+(s=[...b]).splice(i,1))%d||Q(m,d+1,s)for(i in b)],n))('',1,'123456789')
MT0
@ MT0 wow! Das Array-Verständnis schlägt zurück. Ich nehme die erste, weil die andere eine falsche Nummer finden kann, wenn keine richtig ist (IE zählt bis zu 7 statt 9).
edc65
5

Perl, 56

Verwendungszweck: perl -E '...'

{$s++;redo if grep{$s!~$_||substr($s,0,$_)%$_}1..9}say$s

Ausgabe: 381654729

Dieses Programm ist sehr langsam . Wie in mehr als 3,5 Stunden.

Um mehr Spaß zu haben, habe ich beschlossen, einen extrem schnellen Algorithmus zu entwickeln:

my $set = [1..9];
for my $divisor (2..9) {
    my $newset = [];
    for my $element (@$set) {
        my $num = $element * 10;
        for (my $digit = $divisor - ($num % $divisor); $digit < 10; $digit += $divisor) {
            if (index($element, $digit) == -1) {
                push @$newset, $num + $digit;
            }
        }
    }
    $set = $newset;
}

print "@$set\n";

Das Obige läuft in .00095 Sekunden und bestätigt, dass es nur eine Lösung für dieses Problem gibt.

Müller
quelle
5

Python3, 214, 199, 184, 176, 174, 171, 165, 150146

from itertools import*
g=lambda i,d:d==1!=print(i)or int(i[9:])%d==0!=g(i[:-1],d-1)
for x in permutations("123456789"):g("".join(map(str,x))*2,9)

Ausgabe:

381654729

Dies ist mein erstes Golfskript. Hoffe du magst es :)

Hund frisst Katzenwelt
quelle
4

Pyth , 33 Zeichen

=Y]kFkY~Yf>ql{TlT%vTlTm+k`dr1T)pk

Fügen Sie zum Testen den obigen Code als Standardeingabe in den Link im Titel ein.

Nach dem Kompilieren in Python 3.4:

k=''
T=10
Y=[k]
for k in Y:
 Y+=list(filter(lambda T:(len(set(T))==len(T))>(eval(T)%len(T)),
                map(lambda d:k+repr(d),range(1,T))))
print(k)

Erläuterung:

=Y]k::Y=['']

FkY: für k in F:

~Y: Zu Y hinzufügen

f: Filtern nach

>ql{TlT: Alle einzigartigen Elemente und

%vTlT: eval (Element)% len (Element) = 0

m+k` d Auf der Liste von k + repr (d)

r1T: für d von 1 bis 9.

): Ende für Schleife

pk: drucke k

isaacg
quelle
4

Ruby, 66 78 Zeichen

[*r=1..9].permutation{|i|r.all?{|x|eval(i[0,x]*"")%x<1}&&$><<i*""}

Die Laufzeit beträgt ~ 8 Sekunden (Ausgabe nach 3 s gedruckt).

Dies hört nicht auf, nachdem die erste Nummer gefunden wurde. Technisch gesehen werden alle Nummern gedruckt , die die Kriterien erfüllen. Da es jedoch nur eine solche Nummer gibt, macht dies keinen Unterschied.

Ruby 1,8, 63

[*r=1..9].permutation{|i|r.all?{|x|eval(i[0,x]*"")%x<1}&&$><<i}

Im Wesentlichen die gleiche Lösung wie oben. In Ruby 1.8 werden Arrays durch impliziten Aufruf in Strings konvertiert Array#join, sodass wir den Aufruf darin speichern können. Interessanterweise läuft der Code in Ruby 1.8 auch viel schneller als in 2.0 (4,5 Sekunden Gesamtlaufzeit, Ausgabe gedruckt nach 1,6 s).

Ventero
quelle
3

GolfScript (35 Zeichen)

1,{{10*){.)}8*}%{`..&=},{.`,%!},}9*

Online-Demo

Dadurch werden Präfixe erstellt, die die Bedingung erfüllen.

# Initial prefixes: [0]
1,
# Loop 9 times
{
    # Extend each prefix by digits 1 to 9
    {10*){.)}8*}%
    # Filter out ones which repeat a digit
    {`..&=},
    # Filter down to ones which are divisible by their length
    {.`,%!},
}9*
Peter Taylor
quelle
3

Haskell 129 121

Hier ist mein amateurhafter Haskell-Versuch (Vorschläge / Verbesserungen wären sehr dankbar). Es ist möglicherweise nicht das kürzeste, wird jedoch nur ausgeführt.19 65 Sekunden nach Flonks Änderungen auf meinem System.

import Data.List;f=foldl1$(+).(*10);main=print$[f x|x<-permutations[1..9],f[mod(read.take y.show$f x)y|y<-[9,8..1]]<1]!!0
DrJPepper
quelle
Willkommen bei PPCG.SE! Fügen Sie <!-- language: lang-haskell -->vor Ihrem Code zwei Zeilen hinzu, um die Syntax hervorzuheben!
Flonk
Und ich habe tatsächlich einen Weg gefunden, 8 weitere Zeichen zu speichern! Anstatt zu überprüfen, ob jeder Rest == 0 ist, können Sie alle summieren und prüfen, ob dieser == 0 ist, was genauso lang ist. Indem Sie das jedoch foldl1in eine Funktion trennen , können Sie diese anstelle von sumoder verwenden any. import Data.List;f=foldl1$(+).(*10);main=print$[f x|x<-permutations[1..9],f[mod(read.take y.show$f x)y|y<-[9,8..1]]<1]!!0
Flonk
Es scheint, dass Sie Ihre Zeichen einschließlich der nachfolgenden Zeilenumbruch gezählt haben: Ihr Code enthält nur 128 Zeichen.
Peter Taylor
@Flonk Ich liebe die Verwendung der fFunktion für das modPrädikat, um das Schreiben von foldl1 zu vermeiden, obwohl die zusätzlichen Zyklen die Leistung erheblich beeinträchtigen.
DrJPepper
@ DrJPepper 0,65 Sekunden? Meh. Machen wir das noch schlimmer! Sie können auch durch !!0einen Anruf bei ersetzen f, was funktioniert, da nur ein Element in der Liste enthalten ist. Die Liste [9,8..1]kann auch durch ersetzt werden x, da die Reihenfolge keine Rolle spielt. Sprechen Sie über die Wiederverwendung von Code!
Flonk
2

Javascript 75 (Beenden)

Bruteforce-Lösung (super langsam)

for(a=c=1;b=c&&++a;)for(c=9;~(a+'').search(c)&&b%c<1;)--c?b=b/10|0:alert(a)

Wenn Sie das Ergebnis in dieser Lebensdauer sehen möchten, aktualisieren Sie den Anfangswert auf etwa a=c=38e7

Javascript 70 (nicht terminierend)

for(a=1;b=++a;)for(c=9;~(a+'').search(c)&&b%c<1;)--c?b=b/10|0:alert(a)

Und nur zum Spaß eine zufällige Bruteforce, die viel schneller läuft: (nur ES6)

for(a=i=[..."123456789"];b=c=i&&a.sort(x=>Math.random()*9-5|0).join('');)for(i=9;c%i<1;)--i?c=c/10|0:alert(b)
nderscore
quelle
2

Python, 142, 139, 125124

Im Wesentlichen dasselbe wie die Lösung von @ Ventero, wenn ich seinen Code richtig verstanden habe, aber in Python. (Ein Großteil des Kredits geht an @ Greg Hewgill.)

from itertools import*;print[s for s in map(''.join,permutations('123456789'))if all(t(s[:i])%i==0 for i in range(1,9))][0]
Ashwini Chaudhary
quelle
Sie sollten ersetzen können r(9,1,-1)mit r(9), wie die Reihenfolge der Iteration ist nicht wirklich wichtig.
Ventero
Sie müssten verwenden, r(1,9)weil %0ein Fehler vorliegt.
Greg Hewgill
@ GregHewgill Ah, natürlich hast du recht, habe nicht bemerkt, dass es mit 0 beginnt. Ich denke, es ist offensichtlich, dass ich kein Python-Experte bin. :)
Ventero
@Ventero Danke für den Tipp, Greg hat recht, ich muss r(1, 9)in Python verwenden.
Ashwini Chaudhary
1
Verwenden permutations("123456789")und ''.join(s[:i])ist wahrscheinlich kürzer als das, was Sie haben (und dann können Sie beseitigen r=range)
Greg Hewgill
2

Scala (128 Zeichen)

Mein Stich in diese ...

Seq(1,2,3,4,5,6,7,8,9).permutations.filter(p=>(2 to 8)forall{n=>(p.take(n).mkString.toLong%n==0)}).map(_.mkString.toLong).toList
Keith Pinson
quelle
Sie können ein Zeichen speichern, indem Sie das Leerzeichen zwischen (2 to 8)und entfernen forall.
ProgramFOX
@ProgramFOX Ich hatte keine Ahnung. Ich habe immer gedacht, dass dort ein Punkt oder ein Leerzeichen erforderlich ist. Danke, ich habe bis zu 128 Zeichen bearbeitet.
Keith Pinson
2

Perl, 72

Verwendungszweck: perl -M5.010 find-9-digits.pl

{$s=join'',sort{4-rand 8}1..9;redo if grep{substr($s,0,$_)%$_}2..9}say$s

Ausgabe: 381654729

Dieses Programm ist langsam . Es kann länger als 10 Sekunden dauern, da die Ziffern "123456789" gemischt werden, aber das Mischen hat einen Fehler.

Ungolfed:

# Enter a block.
{
     # Shuffle the characters "123456789".
     $s = join('', sort({2 - rand(4)} 1..9));

     # Redo block if any divisiblity test fails; grep returns the
     # number of failing tests.
     redo if grep({
        # For each divisor $_ in 2..9, test if the first $_ digits of
        # of $s are divisible by $_.  The test fails if the remainder
        # is a true value (not zero).
        substr($s, 0, $_) % $_
     } 2..9);
}
say $s;

Ich habe den Code gespielt, der die Ziffern 1..9 mischt:

  • use List'Util shuffle;shuffle 1..9 (34 Zeichen)
  • sort{(-1,1)[rand 2]}1..9 (24 Zeichen)
  • sort{.5<=>rand}1..9 (19 Zeichen)
  • sort(2-rand 4}1..9 (18 Zeichen)
  • sort{4-rand 8}1..9 (18 Zeichen)

Perl erwartet, dass der Sortierblock $ a und $ b auf konsistente Weise vergleicht. Meine Sortierblöcke sehen niemals $ a und $ b . Sie geben eine zufällige Reihenfolge zurück, sodass die Sortierung gemischt wird.

Wenn ich verwenden würde sort{.5<=>rand}1..9, würde mein Programm schneller laufen. Dieser vergleicht 0,5 mit einem zufälligen Float von 0,0 bis 1,0, ohne 1,0, für eine halbe Chance von $ a <$ b und eine fast halbe Chance von $ a> $ b . ( Achtung: Dies ist ein "Microsoft-Shuffle" , das kein faires Shuffle ist. Dies ist voreingenommen, da .5<=>randes keine konsistente Reihenfolge bietet.)

Angenommen, ich spiele einen Charakter weg und benutze den viel schlechteren sort(2-rand 4}1..9. Perl erwartet, dass der Sortierblock eine Ganzzahl zurückgibt, 2-rand 4ist jedoch ein Float. Es ist ein zufälliger Float von -2,0 bis 2,0, ausgenommen -2,0. Perl schneidet diesen Float gegen Null ab, mit folgenden Ergebnissen:

  • 1/4 Chance, dass $ a <$ b , Ganzzahl -1 von -2,0 <float <= -1,0
  • nahe 1/2 Chance, dass $ a == $ b , ganze Zahl 0 von -1,0 <float <1,0
  • nahe 1/4 Chance, dass $ a> $ b , ganze Zahl 1 oder 2 von 1,0 <= float <= 2,0

Wenn $ a == $ b , mischt Perl nicht gut. Mein Programm würde also mehr mischen, bis es genug mischt, wenn 2-rand 4nicht zu oft 0 zurückgegeben wird. Mein Programm würde so langsam laufen, dass es länger als eine Minute dauern könnte.

Ich benutze sort{4-rand 8}1..9, also gibt es nur eine 1/4 Chance, dass $ a == $ b , und mein Programm verwendet weniger Shuffles.

Kernigh
quelle
Netter handgerollter Shuffle
Miller
1

CJam, 35 Bytes

0{)_`$A,1>s=!1$9,{9\m1$\%@+\A/}/;}g

Nach ungefähr 27 Minuten ergibt dies die folgende Ausgabe:

381654729

Wie es funktioniert

0         " Push 0 (“n”).                                                      ";
{         "                                                                    ";
  )_`$    " Increment “N”, duplicate, stringify and sort the resulting string. ";
  A,1>s   " Push '123456789'.                                                  ";
  =!      " Push 0 if the strings are equal and 1 otherwise (“a”).             ";
  1$      " Copy “n”.                                                          ";
  9,{     " For each i in [ 0 1 2 3 4 5 6 7 8 ].                               ";
    9\m   " Calculate “9 - i”.                                                 ";
    1$\%  " Calculate “n % (9 - i)”.                                           ";
    @+    " Add the result to “a”.                                             ";
    \A/   " Swap “a” with “n” and calculate “n / 10”.                          ";
  }/      "                                                                    ";
  ;       " Discard “n”.                                                       ";
}g        " If “a > 0”, repeat the loop.                                       ";
Dennis
quelle
Beeindruckende Größe, aber es scheint noch langsamer als meine, und ich vermute, es ist nicht korrekt
Aditsu beendet, weil SE am
Ich verstehe es nicht ganz, aber es scheint 0 als Ziffer zu akzeptieren? Und wann hört es auf?
Aditsu beendet, weil SE am
1

Python 2 (78)

x=1
while len(set(`10*x`))<=9+sum(x/10**i%(9-i)for i in range(9)):x+=1
print x

Sie müssen keine Permutationen generieren. Probieren Sie einfach jede Zahl aus und prüfen Sie, ob die Ziffern plus 0 unterschiedlich sind. Das Laufen dauert eine Weile.

xnor
quelle
1

SWI-Prolog 84

g([],O,_,O).
g(L,N,I,O):-nth1(_,L,D,R),M is N*10+D,J is I+1,0 is M mod J,g(R,M,J,O).

Es ist ein bisschen betrügerisch, weil die Liste der Ziffern in der Abfrage angegeben werden muss:

?- g([1,2,3,4,5,6,7,8,9],0,0,O).
O = 381654729 ;
false.

Es ist jedoch das, was diesen Code interessant macht: Sie können das Problem für jede Liste von Ziffern lösen. Zum Beispiel:

?- g([1,2,3,4,5,6,7,8,9,0],0,0,O).
O = 3816547290 ;
false.

?- g([1,2,3,4,5,6,7,8],0,0,O).
O = 38165472 ;
false.

?- g([1,2,3,4,5,6,7],0,0,O).
false.

?- g([1,2,3,4,5,6],0,0,O).
O = 123654 ;
O = 321654 ;
false.

?- g([2,2,3,3,5,6,7,8,9],0,0,O).
O = 363258729 ;
O = 363258729 ;
O = 363258729 ;
O = 363258729 ;
O = 723258963 ;
O = 723258963 ;
O = 723258963 ;
O = 723258963 ;
false.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
quelle
1

Python 2 - 114

Nicht einmal die kürzeste Python-Lösung, aber ich teile sie trotzdem:

e=""
f=lambda s,n:[[n,e.join(f(s.replace(j,e),n+j)for j in s)][s>e],e][n>e>0<int(n)%len(n)]
print f("123456789",e)
Wrzlprmft
quelle
1

Bash + Coreutils, 159 Bytes

l=`echo {1..8}`
for d in {2..8};{
l=$(printf "a=%s;if(!a%%$d)a\n" $(eval echo {${l// /,}}{1..8}|tr \  '
'|grep -Pv '(\d).*\1')|bc|paste -d\  -s -)
}
echo ${l}9

Das ist ziemlich lang, aber ich denke, der Algorithmus ist vielleicht einer der schnellsten, wenn man bedenkt, dass dies ein (normalerweise langsames) Shell-Skript ist, das in weniger als 0,1 Sekunden ausgeführt wird.

Der Algorithmus sieht ungefähr so ​​aus:

  • Beginnen Sie mit der Ziffer ganz links (1-8)
  • füge die nächste Ziffer rechts hinzu (1-8)
  • Entfernen Sie alle Zahlen mit wiederholten Ziffern ( grep)
  • Überprüfen Sie die Teilbarkeit durch $d(die Ziffernnummer) bcmit einem Ausdruck, der durch generiert wirdprintf
  • Wiederholen Sie den obigen Vorgang, bis Sie eine 8-stellige Nummer erhalten

Beachten Sie, dass wir einige Abkürzungen verwenden, aber ich denke, diese sind mathematisch fundiert:

  • Die am weitesten links stehende Ziffer muss durch 1 teilbar sein. Dies sind alles Ziffern, daher wird nicht explizit nach dem ersten Satz von Ziffern ganz links gesucht
  • Die Ziffer ganz rechts muss 9 sein (eigentlich bin ich mir nicht sicher, ob dies eine gültige Annahme ist - ich muss ein bisschen darüber nachdenken)
Digitales Trauma
quelle
1

C ++, 187

Ich musste das nur in C ++ versuchen. Natürlich wird es nicht die kürzeste Lösung sein, aber hier ist es:

#include <algorithm>
using namespace std;bool c(int n,int d=9){return d<2||n%d==0&c(n/10,d-1);}int main(){for(char n[]="123456789";next_permutation(n,n+9);)if(c(atoi(n)))return atoi(n);}

Gibt die Nummer zurück, anstatt sie zu drucken, um einige Zeichen zu speichern (verdammt einschließen). Unter POSIX-Systemen wird dies natürlich in ein vorzeichenloses 8-Bit konvertiert und ist daher nicht korrekt - aber das Programm berechnet eine korrekte Zahl.

Ungolfed (erfordert C ++ 11):

#include <iostream>
#include <algorithm>
using namespace std;

bool check(int n, int digit = 9)
{
  return (n % digit==0) && (digit == 1 || check(n/10,digit-1));
}

int main()
{
  string num {"123456789"};
  while (next_permutation(begin(num), end(num)))
    if (check(stoi(num))){
      cout << num << endl;
      break;
    }
}
erlc
quelle
1

T-SQL 2005+ - 203

T-sql ist keine sehr wettbewerbsfähige Golfsprache ...

with A(n)as(select top 10 number from spt_values where'p'=type),R as(select \r,1l union all select r*10+n,l+1from R,A where n not in(select substring(str(r),n,1)from A)and(r*10+n)%l=0)select max(r)FROM R

Muss in der Master-Datenbank ausgeführt werden. Sie können den ersten CTE durch diesen ersetzen, um ihn datenbankunabhängig zu machen. Dann werden jedoch einige weitere Zeichen verwendet (und 2008 erforderlich).

with A as(select*from(VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9))f(n))

Lesbare Formation:

 with A(n)as(select top 10 number from spt_values where'p'=type),
    R as(select \ r,1 l 
        union all 
        select r*10+n,l+1
        from R,A
        where n not in (
            select substring(str(r),n,1)
            from A
        )
        and(r*10+n)%l=0)
select max(r) FROM R

Grundsätzlich fügen wir der Rückseite der rZahl, die wir noch nicht in der Zeichenfolge gesehen haben, weiterhin Ziffern hinzu und stellen sicher, dass die neue Zeichenfolge immer noch Modulo 0 des aktuellen Levels ist. Wir initialisieren R auf \. Dies ist wirklich der einzige Trick in diesem Code. Welches ist eine verrückte Art, es im moneyDatentyp auf 0 zu setzen . Ich vermute, Sie können \statt der Währung tippen . $macht dasselbe in T-SQL, $lwürde aber versuchen, eine Pseudospalte zu interpretieren, die nicht existiert, und einen Fehler auslösen. Auf diese Weise vermeiden wir die Sorge um die VerwendungintDies würde normalerweise bei der 10. Verkettung zu einem Überlauf führen und uns zwingen, den Füllstand tatsächlich zu überprüfen. Bearbeiten: Unterhaltsame Tatsache T-sql verfügt auch 2014 nicht über eine integrierte Möglichkeit, eine Zeichenfolge in eine Wertetabelle umzuwandeln (z. B. keine geteilte Funktion). Daher können wir unsere ATabelle auch zweimal wiederverwenden , um die Zeichen in der zu wiederholen stringified R.

T-SQL-Prioritätsregeln sind ärgerlich, daher müssen wir die numerische Verkettung (* 10 + n) anstelle der Zeichenfolgenverkettung verwenden.

Michael B.
quelle
Sie können 5 Bytes speichern und zulassen, dass es auf allen Arten von Datenbanken ausgeführt wird, indem Sie die erste Zeile durch ersetzen:with A as(select 1n union all select n+1 from A where n<9),
bequem am
Guter Punkt. In echtem Code würde ich niemals einen rCTE zum Zählen verwenden, so dass mir nicht einmal der Gedanke kam, es zu versuchen!
Michael B
0

PHP, 89 Bytes

zufällige Version, 89 Bytes:

for($n=123456789;$n=str_shuffle($n);$d||die("$n"))for($d=10;--$d&&substr($n,0,$d)%$d<1;);

mischt eine Zeichenfolge mit den Ziffern und testet dann die Teilbarkeit in einer Schleife.

Laufen Sie mit -nr.


Brute-Force-Schleife, 90 Byte, sehr langsam:

for(;++$i<1e9;$d||die("$i"))for($d=10;--$d&&max(count_chars($i))<2&substr($i,0,$d)%$d<1;);

Schleifen von 100000001, testen die Teilbarkeit in der inneren Schleife und werden beendet, wenn eine Lösung gefunden wird.


rekursive Funktion, 94 Bytes, sehr schnell:

function f($n="",$e=1){while($d++<9)strpos(_.$n,"$d")|($x=$n.$d)%$e||print$e>8?$x:f($x,$e+1);}

Hängt eine Ziffer an, die noch nicht in der Zahl enthalten ist. Wenn die Teilbarkeit nach Länge angegeben ist, rekursieren (oder drucken).

Dies nutzt aus, dass es nur eine Lösung gibt. ohne dass print$e>8?$x:f($x,$e+1)sein musste print$e>8?"$x\n":f($x,$e+1)(+3 Bytes, drucken alle Lösungen) oder ($e>8?die("$x"):f($x,$e+1))(+4 Bytes Ausfahrt erste Lösung) bzw. die Lösungen würden ohne Trennzeichen gedruckt werden.

Rufen Sie an mit f();

- -

TiO

Die Brute-Force-Version hat aus offensichtlichen Gründen kein TiO, aber Sie können die anderen beiden ausprobieren .

Die Laufzeit des Funktionsaufrufs wird inline gemessen (irgendwo zwischen 2 und 4 Millisekunden);
Die Gesamtlaufzeit wird von der Website gemessen (normalerweise zwischen 50 und 500 ms).

Titus
quelle