Chi è quel poligono?


14

Un modo conveniente e utile per rappresentare le superfici topologiche è con un poligono fondamentale . Ogni lato su un poligono corrisponde a un altro lato e può essere parallelo o anti-parallelo. Ad esempio il qui è il poligono fondamentale di un toro :

Torus

Per capire perché questo è un toro, possiamo immaginare che il nostro poligono sia un foglio di carta. Per rendere la superficie corretta vogliamo piegare la nostra carta in modo che i bordi corrispondenti si allineino con le loro frecce che procedano allo stesso modo. Per il nostro esempio di toro possiamo iniziare arrotolando la carta in un cilindro in modo che i due bordi blu (etichettati b) siano collegati. Ora prendiamo il nostro tubo e lo pieghiamo in modo che i due bordi rossi (etichettati a) si colleghino l'un l'altro. Dovremmo avere una forma a ciambella, chiamata anche toro.

Questo può diventare un po 'più complicato. Se provi a fare lo stesso con il seguente poligono in cui uno dei bordi sta andando nella direzione opposta:

Bottiglia Klein

potresti trovarti nei guai. Questo perché questo poligono rappresenta la bottiglia di Klein che non può essere inserita in tre dimensioni. Ecco un diagramma di Wikipedia che mostra come piegare questo poligono in una bottiglia di Klein:

Piegare una bottiglia di Klein


Come avrai intuito, il compito qui è prendere un poligono fondamentale e determinare quale superficie è. Per i poligoni a quattro lati (le uniche superfici che ti sarà richiesto di gestire) ci sono 4 diverse superfici.

Loro sono

  • Torus

  • Bottiglia Klein

  • Sfera

  • Piano proiettivo

Ora non si tratta quindi non mi aspetto che tu prenda un'immagine come input, invece useremo una notazione conveniente per rappresentare il poligono fondamentale. Potresti aver notato nei due esempi sopra che ho chiamato i bordi corrispondenti con la stessa lettera (o a o b) e che ho dato al bordo ritorto un segno aggiuntivo per mostrarne il contorto. Se iniziamo dal bordo superiore e scriviamo l'etichetta per ciascun bordo mentre procediamo in senso orario, possiamo ottenere una notazione che rappresenta ciascun poligono fondamentale.

Ad esempio il Torus fornito diventerebbe abab e la bottiglia di Klein diventerebbe ab - ab . Per la nostra sfida lo renderemo ancora più semplice, invece di contrassegnare i bordi contorti con un negativo, invece renderemo maiuscole quelle lettere.

Compito

Data una stringa, determina se rappresenta un poligono fondamentale e genera un valore corrispondente alla sua superficie corretta. Non è necessario nominare esattamente le superfici, sono necessari solo 4 valori distinti di output, ognuno dei quali rappresenta una delle 4 superfici con un quinto valore che rappresenta un input errato. Tutti i casi di base sono trattati nella sezione Test semplici , ogni auto sarà isomorfa rispetto a una o non valida.

Regole

  • I lati non saranno sempre etichettati con aeb, ma saranno sempre etichettati con lettere.

  • L'input valido sarà composto da 4 lettere, due di un tipo e due di un altro. È sempre necessario produrre la superficie corretta per un input valido.

  • È necessario rifiutare (non emettere nessuno dei 4 valori che rappresentano le superfici) input non valido. È possibile fare qualsiasi cosa quando si rifiuta un input, purché sia ​​distinguibile dalle 4 superfici

  • Questo è quindi l'obiettivo è ridurre al minimo il numero di byte nel codice sorgente.

test

Test semplici

abab Torus
abAb Klein Bottle
abaB Klein Bottle
abAB Projective Plane
aabb Klein Bottle
aAbb Projective Plane
aabB Projective Plane
aAbB Sphere
abba Klein Bottle
abBa Projective Plane
abbA Projective Plane
abBA Sphere

Test più complicati

ABAB  Torus
acAc  Klein Bottle
Emme  Projective Plane
zxXZ  Sphere
aaab  Bad input
abca  Bad input
abbaa Bad input
ab1a  Bad input

Perché ababun toro e aabbuna bottiglia di Klein?
Neil,

@Neil ababè l'esempio nel primo paragrafo, puoi cercare una spiegazione lì. Ecco un'immagine che mostra perché aabbè la stessa di abAbuna bottiglia di Klein.
Post Rock Garf Hunter,

1
Quali input errati dobbiamo gestire e identificare come errati? Tutte le stringhe possibili? ASCII stampabile? Qualche limite di lunghezza? Se scriviamo una funzione, potrebbe essere passato un oggetto non stringa? In realtà, tutta questa attività di elaborazione degli input mi sembra una sfida camaleontica.
xnor

1
@WheatWizard In tal caso, puoi chiarirlo nel titolo e nel corpo? Sembra matematica fino alle Regole, e anche lì è facile perdere il requisito del gamechanging per convalidare piuttosto che classificare.
xnor

2
Separatamente, penso che manchi una spiegazione di ciò che rende una stringa classificata in una determinata categoria, dal momento che sembra che non ti aspetti che le persone facciano i conti con la classificazione. Penso di poter risolvere le regole dai casi di test, ma è tutt'altro che ideale.
xnor

Risposte:


6

Retina , 123 byte

i`(.)(\1..)
$2$1
iG`^([a-z])(?!\1)([a-z])(\1\2|\2\1)$
(..)\1
T
.*(.).\1.*|(.)(.)\3\2
B
(.)..\1|.(.)\2.
P
i`(.)..\1
S
....
P

Provalo online! Grazie a @JonathanAllen per aver segnalato un bug nel mio codice e anche come salvare alcuni byte; Ho anche giocato a golf un po 'più di byte, quindi non posso attribuirgli una cifra specifica. Spiegazione:

i`(.)(\1..)
$2$1

Se le prime due lettere sono uguali (ignorando il caso), sposta la prima lettera in quarta. Ciò riduce il numero di casi che devo testare.

iG`^([a-z])(?!\1)([a-z])(\1\2|\2\1)$

Se non ci sono esattamente quattro lettere, o le prime due sono uguali, o le ultime due lettere non duplicano le prime due, quindi eliminare tutto.

(..)\1
T

Il toro è il caso semplice: una coppia di lettere, caso di corrispondenza ripetuta.

.*(.).\1.*|(.)(.)\3\2
B

Se una delle coppie corrisponde al caso (nel qual caso l'altra coppia deve non corrispondere al caso), allora quella è una bottiglia di Klein. In alternativa, se la coppia corrisponde al caso ma è invertita, allora è anche una bottiglia di Klein.

(.)..\1|.(.)\2.
P

Se d'altra parte la coppia è invertita, ma solo una coppia corrisponde al caso, allora quello è un piano proiettivo.

i`(.)..\1
S

E se la coppia è invertita ma non corrisponde a maiuscole e minuscole, quella è una sfera. ( i`.(.)\1.funzionerebbe anche.)

....
P

Tutto il resto è un piano proiettivo.


1
@JonathanAllan Grazie per la punta; speriamo che questa versione abbia una migliore validazione.
Neil,

Se solo potessi elaborare la logica da solo: p
Jonathan Allan,

1

Gelatina , 52 51 58 byte

+7 byte, ho scoperto che la mappatura che avevo usato non funzionava per alcuni scenari (fuori esempio) di modifica dei casi.

“nḲ⁾⁶ƥ¦ṃṗḋ’b4s4‘µṙJ;U$µ€
,ŒsṢÞṪµŒlĠL€⁼2,2ȧ⁸i@€ṢeЀ¢TṪ’:3,8

Un collegamento monadico che prende una stringa e restituisce i seguenti cinque valori distinti e coerenti:

  • [-1,-1] - inserimento non valido
  • [0,0] - piano proiettivo
  • [1,0] - Bottiglia di Klein
  • [2,0] - sfera
  • [2,1] - toro

Provalo online! o vedi la suite di test .

Come?

Qualsiasi poligono fondamentale è:

  • invariato in rotazione - si può girare la carta come un volante
  • invariato nella riflessione - si può capovolgere la carta
  • invariato in caso di inversione del caso - si possono scambiare as e se Ae / o scambiare bs e Bs senza alcun effetto - poiché vogliamo abbinare le direzioni in cui l'etichetta reale è irrilevante.

Come tale ci sono nove classi di equivalenza. Il codice crea elenchi di quattro numeri interi ciascuno dei quali rappresenta un esempio di una delle nove classi di equivalenza, crea le quattro rotazioni di ciascuna, riflette ciascuna di esse e quindi controlla se esiste una forma tradotta dell'input in ciascuna lista. Le classi sono ordinate P,P,P,K,K,K,S,S,T, quindi prendendo l'intero indice dell'indice basato su 0 diviso per ciascuno dei [3,8]rendimenti i quattro output validi (l'indicizzazione è basata su 1 e l'atomo eritorna 0per inesistenza, quindi sottraendo 1e dividendo il numero intero per ciascuno dei [3,8]rendimenti [-1,-1]per il caso non valido ).

“nḲ⁾⁶ƥ¦ṃṗḋ’b4s4‘µṙJ;U$µ€ - Link 1, symmetries of the 9 equivalence classes: no arguments
“nḲ⁾⁶ƥ¦ṃṗḋ’              - base 250 number                 1704624888339951310984
           b4            - convert to base 4               [1,1,3,0,1,2,2,0,1,2,3,0,0,2,2,0,1,3,1,0,2,1,2,0,2,3,1,0,3,1,2,0,2,0,2,0]
             s4          - split into 4s                   [[1,1,3,0],[1,2,2,0],[1,2,3,0],[0,2,2,0],[1,3,1,0],[2,1,2,0],[2,3,1,0],[3,1,2,0],[2,0,2,0]]
               ‘         - increment (vectorises)          [[2,2,4,1],[2,3,3,1],[2,3,4,1],[1,3,3,1],[2,4,2,1],[3,2,3,1],[3,4,2,1],[4,2,3,1],[3,1,3,1]]
                µ     µ€ - for €ach:                       ...e.g. [2,2,4,1]:
                  J      -   range of length               [1,2,3,4]
                 ṙ       -   rotate left by (vectorises)   [[2,4,1,2],[4,1,2,2],[1,2,2,4],[2,2,4,1]]
                     $   -   last two links as a monad:
                    U    -     upend (reverse each)        [[2,1,4,2],[2,2,1,4],[4,2,2,1],[1,4,2,2]]
                   ;     -     concatenate                 [[2,4,1,2],[4,1,2,2],[1,2,2,4],[2,2,4,1],[2,1,4,2],[2,2,1,4],[4,2,2,1],[1,4,2,2]]

,ŒsṢÞṪµŒlĠL€⁼2,2ȧ⁸i@€ṢeЀ¢TṪ’:3,8 - Main link: string s      e.g. "xOxO"
 Œs                               - swap case                     "XoXo"
,                                 - pair with s                   ["xOxO","XoXo"]
    Þ                             - sort by:
   Ṣ                              -   sort                        ["xOxO","XoXo"]
     Ṫ                            - tail                          "XoXo"
      µ                           - monadic chain separation, call that v
       Œl                         - convert to lowercase          "xoxo"
         Ġ                        - group indices by value        [[2,4],[1,3]]
          L€                      - length of each                [2,2]
             2,2                  - 2 pair 2                      [2,2]
            ⁼                     - equal? (1 if so, 0 if not)    1
                 ⁸                - link's left argument, v       "XoXo"
                ȧ                 - and (v if equal, 0 if not)    "XoXo"
                     Ṣ            - sort v                        "XoXo"
                  i@€             - first index for €ach          [1,3,1,3]
                         ¢        - call the last link (1) as a nilad
                       Ѐ         - map over right:
                      e           -   exists in?                  [0,0,0,0,0,0,0,0,1]
                          T       - truthy indexes                [                9]
                           Ṫ      - tail (empty list yields 0)    9
                            ’     - decrement                     8
                              3,8 - 3 pair 8                      [3,8]
                             :    - integer division (vectorises) [2,1]

Nota: 11 byte ( ŒlĠL€⁼2,2ȧ⁸) convalidano solo la stringa di input come della forma corretta - senza questo codice passa ogni caso di esempio tranne che ab1aviene valutato come se fosse abBa, un piano proiettivo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.