Welches Sternzeichen hast du?

13

Schreiben Sie ein Programm, das ein Geburtsdatum (Monat und Tag des Monats) als Eingabe verwendet und das entsprechende Zeichen, Element und die Qualität des westlichen Tierkreises ausgibt . Für die Zwecke dieser Herausforderung werden diese genau wie in der Tabelle auf der verknüpften Wikipedia-Seite definiert:

Sign           Date Range                    Element    Quality

Aries          March 21 to April 19          Fire       Cardinal
Taurus         April 20 to May 20            Earth      Fixed
Gemini         May 21 to June 21             Air        Mutable
Cancer         June 22 to July 22            Water      Cardinal
Leo            July 23 to August 22          Fire       Fixed
Virgo          August 23 to September 22     Earth      Mutable
Libra          September 23 to October 23    Air        Cardinal
Scorpio        October 24 to November 20     Water      Fixed
Sagittarius    November 21 to December 22    Fire       Mutable
Capricorn      December 23 to January 20     Earth      Cardinal
Aquarius       January 21 to February 21     Air        Fixed
Pisces         February 22 to March 20       Water      Mutable

Regeln

  • Das Zeichen, Element und die Qualität werden ab dem Eingabedatum genau nach der Wikipedia-Tabelle berechnet.
  • Ich gebe etwas Freiheit über das Eingabe-Datumsformat (siehe Abschnitt Eingabe unten). Sie müssen in Ihrer Antwort klar angeben, welches Format Sie verwenden.
  • Wenn ein ungültiges Datum angegeben wird (nicht analysierbares Datum oder Monat oder Monatstag außerhalb des gültigen Bereichs), wird das Programm mit der Meldung beendet Invalid date.
  • Das Programm muss Schaltjahre korrekt handhaben. dh wenn der 29. Februar der Eingang ist, muss der Ausgang korrekt sein Pisces, Water, Mutable.
  • Die Datumsbibliotheken / APIs Ihrer Sprache sind zulässig, aber alle APIs, die speziell Sternzeichen berechnen, sind verboten.
  • Standard "Schlupflöcher", die nicht mehr lustig sind
  • Das ist , also gewinnt die kürzeste Antwort in Bytes.

Eingang

  • Das Programm kann das Eingabedatum von STDIN, Befehlszeile, Umgebungsvariablen oder einer anderen für Ihre Sprache geeigneten Methode lesen.
  • Dies ist nicht in erster Linie eine Übung zum Analysieren von Datenreihen. Daher kann die Eingabezeichenfolge in einem von Ihnen gewählten Format bereitgestellt werden, sofern sie nur aus Monats- und Tag-von-Monat-Komponenten und keinen anderen Werten (wie Jahr oder Uhrzeit) besteht. . ZB Jul 24oder 24th of Julyoder 7/24oder 24/07oder welches Format auch immer ist bequem. Wenn eine Eingabe eingegeben wird, die nicht dem von Ihnen gewählten Eingabeformat entspricht, Invalid datemuss der Fehler ausgegeben werden.

Ausgabe

  • Das Programm gibt STDOUT, ein Dialogfeld oder eine andere für die Sprache Ihrer Wahl geeignete Anzeigemethode aus.
  • Das Ausgabeformat ist das durch Komma und Leerzeichen getrennte Zeichen, Element und die Qualität: Sign, Element, Quality

Beispiele

Input                 Output
1/1                   Capricorn, Earth, Cardinal
2/29                  Pisces, Water, Mutable
7/24                  Leo, Fire, Fixed
13/1                  Invalid date
2/31                  Invalid date
-1/-1                 Invalid date
1st of Golfember      Invalid date
Digitales Trauma
quelle
Ist die Erkennung / Warnung eines ungültigen Datums erforderlich? Wenn ja, können wir davon ausgehen, dass ungültige Zahlen, die vom Benutzer eingegeben wurden, größer als Null sind? (Ich vermute, die meisten Leute werden ein numerisches Datumsformat verwenden.)
Level River St
1
@steveverrill Ich glaube, ich habe das im dritten Punkt der Regeln klargestellt, aber ich habe den Eingabeabschnitt bearbeitet, um dies zu verdeutlichen. TLDR gültige Eingabe => gültige Ausgabe; ungültige Eingabe => Fehlermeldung; Für eine bestimmte Eingabe ist kein "undefiniertes Verhalten" zulässig.
Digital Trauma
ist ein voller Termin erlaubt? Tage, Monate und Jahre?
Teun Pronk
@TeunPronk Nein, nur Monat und Tag des Monats. Ich habe die Eingaberegel geklärt.
Digital Trauma
Ist der Tag des Jahres (zB Jan 21 -> 21, Feb 5 -> 36) ein gültiges Eingabeformat?
Mego

Antworten:

8

JavaScript, 285 Bytes

(Meine erste Antwort hier nach einer Weile hier lauern)

d=prompt(m=prompt(e='MutableCardinalFixedAirWaterFireEarthCapricornAquariusPiscesAriesTaurusGeminiCancerLeoVirgoLibraScorpioSagittarius'.match(/[A-Z][a-z]+/g)));alert(m>0&m<13&d>0&d<29-~'202121221212'[--m]?e[n=7+m%12+(d>18-~'121012333413'[m])]+', '+e[n%4+3]+', '+e[n%3]:'Invalid date')

Der erste prompt()ist der Monat in numerischer Form, und der zweite prompt()ist der Tag des Monats (Ignorieren Sie den Text der Eingabeaufforderung). Führende Nullen sind für beide optional. Die Ausgabe wird mit angezeigt alert(). (Dank an bitpwner, Snack, edc65 und core1024 für die Kürzung des Codes.)

Versuchen Sie es oben mit Stack Snippets oder unter http://jsfiddle.net/8vq89/5/ .

Code mit Leerzeichen und Kommentaren, um die hinzugefügten verwirrenden Teile zu erklären:

var m = prompt(), d = prompt(),
e = 'MutableCardinalFixedAirWaterFireEarthCapricornAquariusPiscesAries\
TaurusGeminiCancerLeoVirgoLibraScorpioSagittarius'.match(/[A-Z][a-z]+/g);
alert(m > 0 && m < 13 && d > 0
      & d < 29 - ~'202121221212'[--m] /* ~ is bitwise NOT, which yields -(x + 1). It also
                                         converts a string to a number. Subtracting that
                                         number from 29 gives the number of days in the
                                         month given. */
      ? e[n = 7 + // 7 is added to skip over the 7 qualities and elements in array e.
      m % 12 // The modulus allows dates near the end of December to wrap around to January.
      + (d > 18 - ~'121012333413'[m])] + ', ' +
      e[n % 4 + 3] + /* Qualities and elements follow a pattern, so the modulus determines
                        which one it is. 3 is added to skip over the 3 qualities. */
      ', ' + e[n % 3] : 'Invalid date')
NinjaBearMonkey
quelle
1
Für 'Cardinal0Fixed0Mutable'.split(0)und 'Earth0Air0Water0Fire'.split(0), ['Cardinal','Fixed','Mutable']und ['Earth','Air','Water','Fire']ist ein wenig kürzer.
Snack
Ich hatte eine Lösung, aber auch ähnlich: z='Air9Water9Fire9Earth9Fixed9Mutable9Cardinal9Aquarius9Pisces9Aries9Taurus9Gemini9Cancer9Leo9Virgo9Libra9Scorpio9Sagittarius9Capricorn'.split(9); [m,d]=prompt().split(/\D/); alert([m-->0&m<12&d>0&d<(32-'020101001010'[m])?z[(m+=(18-~'121012333413'[m]<d)+11)%12+7]+', '+z[m%4]+', '+z[m%3+4]:'Invalid date']). Schauen Sie sich die Single Split an
edc65 25.07.14 um 15.05
@ edc65 Ich erhalte eine Invalid left-hand side in assignmentFehlermeldung, wenn ich versuche, das auszuführen, wahrscheinlich aufgrund der Eingabeaufforderung
NinjaBearMonkey
Gruppenzuweisung ist Ecmascript 6, funktioniert nur in Firefox. p=prompt().split(/\D/),m=p[0],d=p[1]sollte funktionieren (aber so länger)
edc65
3
Sie können es noch kürzer machen, wenn Sie '...ScorpioSagittarius'.match(/[A-Z][a-z]+/g)anstelle von'...Scorpio0Sagittarius'.split(0)
core1024 31.07.14 um 19.03
3

C 353 352

Bearbeiten Behobener Fehler und Tippfehler, 1 Zeichen mehr

Bevor Sie fragen: Ja, auch ohne #include ist gültiger und funktionierender C-Standard.
Eingabeformat: zwei Zahlen, erster Monat, dann Tag.

char*s[]={"Air","Water","Fire","Earth","Fixed","Mutable","Cardinal","Aquarius","Pisces","Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn"};
main(m,d){
  scanf("%d%d",&m,&d);
  m>0&m<13&d>0&d<(32-(4460832>>m>>m&3))
  ?m+=10+(" 121012333413"[m]-29<d),printf("%s, %s, %s\n",s[m%12+7],s[m%4],s[m%3+4])
  :puts("Invalid date");
}

Prüfung

char*s[]={"Air","Water","Fire","Earth","Fixed","Mutable","Cardinal","Aquarius","Pisces","Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn"};
char *test(char *o, int m, int d)
{
  char *result=o;
  m>0&m<13&d>0&d<(32-(4460832>>m>>m&3))
  ?m+=10+(" 121012333413"[m]-29<d),sprintf(o, "%s, %s, %s\n",s[m%12+7],s[m%4],s[m%3+4])
  :(result = 0);
  return result;
}

int main()
{
  char buf[100];
  int m,d;
  for (m=0;m<14;m++)
    for(d=0;d<40;d++)
      if (test(buf, m,d)) printf("%d %d %s", m, d, buf);
  return 0;
}
edc65
quelle
Gut, bis auf den Tippfehler von Ivalid;-)
Digital Trauma
@DigitalTrauma Nicht so gut, vielleicht hat es einen Fehler bei der Unterscheidung von Startzeichen (21, 20, 24 usw.). Ich überarbeite es gerade. Bleiben Sie dran
edc65
2

Perl 287 (286 + 1 für die -pFlagge)

/\//;$_=32-(26830452>>$`*2&3)<$'|$'<1|$`<1|$`>12?'Invalid date
':qw(Aquarius01 Pisces23 Aries45 Taurus61 Gemini03 Cancer25 Leo41
Virgo63 Libra05 Scorpio21 Sagittarius43
Capricorn65)[$`-1-($'<20+(219503166088>>$`*3&7))].$/;s/\d/', '.qw(Air
Fixed Water Mutable Fire Cardinal Earth)[$&]/eg

Die Eingabe erfolgt von STDIN und die Ausgabe geht an STDOUT. Hier sind die Tests von OP:

1/1
Capricorn, Earth, Cardinal
2/29
Pisces, Water, Mutable
7/24
Leo, Fire, Fixed
13/1
Invalid date
2/31
Invalid date
-1/-1
Invalid date
1st of Golfember
Invalid date
core1024
quelle
1

Python, 447 387 Zeichen

import sys
try:S=sys.argv[1];a,b=int(S[:2])-1,int(S[3:])
except:a=b=0
print['Invalid date',', '.join((s.split()*5)[a+(b>[20,21,20,19,20,21,22,22,22,23,20,22][a%12])]for s in"Capricorn Aquarius Pisces Aries Taurus Gemini Cancer Leo Virgo Libra Scorpio Sagittarius Capricorn|Earth Air Water Fire|Cardinal Fixed Mutable".split("|"))][-1<a<12and 0<b<[32,30,32,31,32,31,32,32,31,32,31,32][a]]

Nimmt Eingabe als MM / DD, muss immer zweistellig sein.

$ python zods.py 01/01
Capricorn, Earth, Cardinal
$ python zods.py 02/29
Pisces, Water, Mutable
$ python zods.py 07/24
Leo, Fire, Fixed
$ python zods.py 13/01
Invalid date
$ python zods.py 02/31
Invalid date
$ python zods.py -1/-1
Invalid date
$ python zods.py First of golfember
Invalid date
$ python zods.py
Invalid date
Claudiu
quelle
1
Sie können diese versuchen: [20,21,20,19,20,21,22,22,22,23,20,22][a%12]-> 19+int('121012333413'[a%12]) und [32,30,32,31,32,31,32,32,31,32,31,32][a]->30+int('202121221212'[a])
Vectorized
1

Javascript, 403 396 Bytes

M=prompt(),D=+prompt(),i=[52,85,117,147,180,213,246,278,310,343,372,406,415];if([0,0,-2,0,1,0,1,0,0,1,0,1,0][M]<D-31||M<1||D<1||M>12)alert("Invalid date");else for(x in i)if(M*32+D<=i[x]){alert("Capricorn0Aquarius0Pisces0Aries0Taurus0Gemini0Cancer0Leo0Virgo0Libra0Scorpio0Sagittarius0Capricorn".split(0)[x]+", "+["Earth","Air","Water","Fire"][x%4]+", "+["Cardinal","Fixed","Mutable"][x%3]);break}

Ein anderer Ansatz. Ich denke, ich kann mehr Golf spielen, aber später.

Geben Sie bei der ersten Eingabeaufforderung den Monat und bei der zweiten Eingabeaufforderung das Datum ein.

Snack
quelle
1

PHP - 294 Bytes (ohne PHP-Tags *)

* Wie der andere PHP-Eintrag

Eingabe: Month Dayals Ganzzahl, führende Null nicht erforderlich.

Bsp .: php starsign.php <<< "2 29"für den 29. Februar.

Golf (nicht direkt kopieren, siehe unten):

<?@eval(gzinflate('=Œ1Â0…ÿŠC!Ë
¦q+JQ—
BEq¸¶¡Ô¤^ðç{¤"ï>/Ãò®`³GOBqú7v¥±MP#äpúµ;$:Å€Ý$“g¦Þ³ƒê‘).p¦¥·TL’Œ,ÝѾȑ¬]oëáJ<zh¨c„V3yhq¤VË_ü(²®TZË¥ØêܳÓF_'));die(fscanf(STDIN,'%u%u',$m,$d)/2&$m<13&&$m*$d&&$d<33-$b[$m]?$a[7+$m-=$d<20+$b[$m+9]].$a[$m%4].$a[$m%3+4]:'Invalid date');

Hexdump der PHP-Datei:

3f3c 6540 6176 286c 7a67 6e69 6c66 7461
2865 3d27 318c c20b 1030 ff85 438a cb21
a60d 2b71 4a1d 9751 420a 0745 b871 a1b6
d41e 5ea4 f013 7be7 22a4 ef07 1e3e 2f8f
f2c3 60ae 47b3 4f0e 4205 7115 37fa 760c
03a5 4db1 2350 e40f fa70 1fb5 243b c53a
dd80 9324 671a dea6 83b3 1dea 2991 702e
a5a6 0bb7 4c54 1792 2c8c d1dd c8be ac91
6f5d 1a19 e1eb 3c4a 687a 63a8 5684 3304
6879 a471 5610 5fcb 28fc aeb2 5a54 9d1b
a5cb ead8 18dc d3b3 1546 275f 2929 643b
6569 6628 6373 6e61 2866 5453 4944 2c4e
2527 2575 2775 242c 2c6d 6424 2f29 2632
6d24 313c 2633 2426 2a6d 6424 2626 6424
333c 2d33 6224 245b 5d6d 243f 5b61 2b37
6d24 3d2d 6424 323c 2b30 6224 245b 2b6d
5d39 2e5d 6124 245b 256d 5d34 242e 5b61
6d24 3325 342b 3a5d 4927 766e 6c61 6469
6420 7461 2765 3b29

Um eine Golf-Datei zu generieren, führen Sie das folgende PHP-Skript aus (generiert bis starsign.php):

<?php
$a=<<<'NOW'
$a=[', Earth',', Air',', Water',', Fire',', Cardinal',', Fixed',', Mutable',Capricorn,Aquarius,Pisces,Aries,Taurus,Gemini,Cancer,Leo,Virgo,Libra,Scorpio,Sagittarius,Capricorn];$b='1131212112121012333413';
NOW;
$p = '<?@eval(gzinflate(\'';
$s = <<<'NOW'
'));die(fscanf(STDIN,'%u%u',$m,$d)/2&$m<13&&$m*$d&&$d<33-$b[$m]?$a[7+$m-=$d<20+$b[$m+9]].$a[$m%4].$a[$m%3+4]:'Invalid date');
NOW;
file_put_contents('starsign.php',$p . gzdeflate($a) . $s);

Völlig ungolfed version:

<?php
$a=[', Earth',', Air',', Water',', Fire',', Cardinal',', Fixed',', Mutable',Capricorn,Aquarius,Pisces,Aries,Taurus,Gemini,Cancer,Leo,Virgo,Libra,Scorpio,Sagittarius,Capricorn];$b='1131212112121012333413';
if(fscanf(STDIN, '%u%u', $m, $d) == 2
 and $m < 13
 and $m 
 and $d
 and $d < 33-$b[$m]){
    if($d < 20 + $b[$m+9])
        --$m;
    die($a[7+$m] . $a[$m%4] . $a[$m%3+4]);
}else die('Invalid date');
es1024
quelle
Schließlich fand ich heraus, dass ich /etc/php5/cli/php.ini bearbeiten und festlegen muss short_open_tag = On, damit dies funktioniert. Funktioniert für diese Antwort, aber die andere PHP-Antwort ist immer noch fehlerfrei. +1 für diesen.
Digital Trauma
1

Python 3 - 332 Bytes

s="Capricorn Aquarius Pisces Aries Taurus Gemini Cancer Leo Virgo Libra Scorpio Sagittarius Earth Air Water Fire Cardinal Fixed Mutable".split()
import sys
try:m,d=map(int,sys.argv[1:]);13>m>0<d<b" 313232332323"[m]-19or E
except:x="Invalid date"
else:i=m-1+(d>b" 121012333413"[m]-29);x=s[i%12]+", "+s[-7+i%4]+", "+s[-3+i%3]
print(x)
  • Nimmt Eingaben als separate Argumente (zB 1 1)

  • Ein Split für alle Saiten

  • Indizieren von Bytes in py3 ergibt die ord

  • or Eist eine kostengünstige Möglichkeit, eine Ausnahme zu generieren ( NameError)

  • Gibt es eine billigere Möglichkeit, die Zeichenfolgen zu verketten? +und Literale erwiesen sich als kleiner als join.

  • Es gibt keinen guten Grund, warum eine Bytesuche mit 1 und die andere mit 0 beginnt. Ich habe nur den 29-tägigen Februar vergessen und 0-> 1 geändert, anstatt das Ganze zu wiederholen.

Jason S
quelle
0

PHP 548 524 502 419 (ohne PHP-Tags)

Benötigt PHP> = 5.4.0

Eingabe: Day Month(Zahlenwert ab 1) zB 2 3für den 2. März.

<?
$x='Invalid date';
@list($d,$m)=split(' ',fgets(STDIN));
if(@$m<1||$m>12||@$d<1)die($x);
$z=['Aquarius','Pisces','Aries','Taurus','Gemini','Cancer','Leo','Virgo','Libra','Scorpio','Sagittarius','Capricorn','Air','Water','Fire','Earth','Fixed','Mutable','Cardinal','121012333413202121221212'];
$m=$m+0;$d<$z[19][--$m]+20&&$m--;$m<0&&$m=11;$d>$z[19][$m+12]+29&&die($x);
echo$z[$m+0],", {$z[$m%4+12]}, {$z[$m%3+16]}";

BEARBEITEN: Der A non well formed numeric valueHinweis wird durch Ausführen eines Vorinkrements für die Zeichenfolge verursacht $m. Unabhängig von der Meldung sollte die folgende Ausgabe immer noch korrekt sein. Dieser Hinweis variiert je nach Version von PHP. Um dies zu beheben, sollte eine einfache Umwandlung von Zeichenfolge in Ganzzahl vor der vorletzten Zeile stehen. Ich habe den Code mit den Konvertierungen aktualisiert.

Beispiel für Ein- / Ausgabe (unter Windows):

// March 2nd
Input > echo 2 3 | php star.php
Output > Pisces, Water, Mutable

// Feb. 30th
Input > echo 30 2 | php star.php
Output > Invalid date

// June 30th
Input > echo 30 6 | php star.php
Output > Cancer, Water, Cardinal
noahnu
quelle
OK, ich bin ein PHP-Dummy. Wie läuft das ab? Ich habe es versucht echo 2 3 | php -f zod.php, aber es gibt das Skript nur an STDOUT
Digital Trauma weiter.
1
@DigitalTrauma Ich denke, dass Sie die kurzen Tags in Ihrem Interpreter aktivieren müssen , ansonsten verwenden Sie <?phpstatt <?.
Core1024
Ich habe es versucht, aber jetzt verstehe ich PHP Notice: A non well formed numeric value encountered in /home/ubuntu/zod.php on line 6. Ich laufe PHP 5.5.9 auf Ubuntu 14.04
Digital Trauma
Code behoben. Siehe Bearbeiten.
Noahnu