Verifica il numero di nascita


9

Un numero di nascita norvegese è composto da 11 cifre, composte nel modo seguente:

DDMMYYiiikk
  • DD è il giorno (dal 01-31)
  • MM è il mese (dal 01-12)
  • YYè l'anno (dalle 00-99). Non è differenziato tra il 1900 e il 2000
  • iii è il "numero individuale"
  • kk sono due cifre di controllo

iii è determinato dalla nascita e dal genere nel modo seguente

  • Funzionamento1900: Ignorare, ci sono alcune incoerenze e casi speciali
  • 1900-1999: intervallo = 000-499
  • 2000-2039: intervallo = 500-999
  • Femmina: numeri pari (e 000)
  • Maschio: numeri dispari

I numeri di controllo sono determinati nel modo seguente:

Chiamiamo le 11 cifre:

d1 d2 m1 m2 y1 y2 i1 i2 i3 k1 k2

Quindi le cifre di controllo possono essere calcolate usando le equazioni:

k1 = 11 - ((3 * d1 + 7 * d2 + 6 * m1 + 1 * m2 + 8 * y1 + 9 * y2 + 4 * i1 + 5 * i2 + 2 * i3) mod 11)

k2 = 11 - ((5 * d1 + 4 * d2 + 3 * m1 + 2 * m2 + 7 * y1 + 6 * y2 + 5 * i1 + 4 * i2 + 3 * i3 + 2 * k1) mod 11).

Per alcune combinazioni, i numeri di controllo k1o k2possono diventare 10. In tal caso, il numero non sarà valido.

Se il modulo di somma 11 per k1o k2è 11, ovvero k1 = 11 - (11 mod 11), la cifra di controllo sarà 0, non 11.

Sfida

Prendi una lettera Mo F(maschio o femmina) e un numero di undici cifre come input e controlla se il numero di nascita è valido secondo le regole sopra.

  • Il formato e l'ordine di input sono facoltativi
  • Gli 11 numeri devono essere un singolo numero o una stringa consecutiva (non è possibile accettare l'input come DD, MM, YY, iii, kk).
  • Puoi presumere che la data sia valida (310699xxxxx non verrà fornito come input)
  • L'output è un valore di verità / falsa (1/0, vero / falso ecc.)
  • Programma o funzione
  • Si applicano tutte le regole standard

Puoi trovare tutti i numeri validi in questa pagina (in norvegese) scegliendo una data.

Esempi:

M, 01010099931
True

F, 01029042620
True

M, 0101009841
False

F, 01010051866
True  

F, 08021690849
True

M, 01029040105
True

M, 01029037473
False

Il codice più corto in byte vince.


Dobbiamo gestire generi diversi da M e F? (È contro le regole se ["Q", "01010099931"]ritorna true?)
Chiru

@Chiru, supponiamo che sia dato solo M o F come input. Il comportamento indefinito per input non valido è OK.
Stewie Griffin,

Risposte:


2

Python 3, 227 221 byte

Funzione che accetta due argomenti, il genere 'm' e il numero di nascita 'n', entrambi come stringhe. Potrebbe esserci ancora del golf da fare, specialmente nell'ultima riga. Continuerò a lavorarci su.

def a(m,n):
 o=[3,7,6,1,8,9,4,5,2];t=[5,4,3,2,7,6,5,4,3,2];n=list(map(int,n));y=z=b=0;q=11
 for i in n[:9]:z+=o[b]*i;y+=t[b]*i;b+=1
 print((q-z%q)%q==n[9] and (q-(y-z-z)%q)%q==n[-1] and len(n)<12 and ord(m)%2==n[8]%2)

2

JavaScript (ES2016), 275 259 255 254 252 Bytes

Golfato :

f=(g,I)=>{[,d,m,y,i,k]=/(..)(..)(..)(...)(..)/.exec(I.padEnd(12)),v=g.charCodeAt()%2!=i%2|y<=39&i<500,s=k=>11-([...I].slice(0,-2).map((e,i)=>e*[..."376189452543276543"][i+!k|9]).reduce((a,b)=>a+b)+2*k)%11,[s(0),s(s(0))].map((s,i)=>v&=k[i]!=s);return!v}

Test :

for (let args of [
    ["M", "01010099931"], // true
    ["F", "01029042620"], // true
    ["M", "0101009841"],  // false
    ["F", "01010051866"], // true
    ["F", "08021690849"], // true
    ["M", "01029040105"], // true
    ["M", "01029037473"]  // false
]) {
    console.log(f(...args));
}

Ungolfed :

let f = (g, input) => {

    /* Sanitize input, destructure arguments via RegExp */
    let [, d, m, y, i, k] = /(..)(..)(..)(...)(..)/.exec(input.padRight(12));

    /* Validate gender and year */
    let violation = g.charCodeAt() % 2 != i % 2 | y <= 39 & i < 500;

    let n = [..."376189452543276543"];
    /* This function computes k1 if given no arguments, k2 if given one argument */
    let s = k => 11 - ([...input].slice(0, -2).map((e, i) => e * n[i + !k | 9]).reduce((a, b) => a + b) + 2 * k) % 11;

    /* Validate the control numbers k */
    [s(0), s(s(0))].map((s, i) => violation &= k[i] != s);

    return !violation;
}

1

JS, 343 byte

x=prompt().replace(/F/,1).replace(/M/,2).match(/\d{1}/g);v=Math.abs((x[0]-x[9])%2);v++;t=x[5]*10+x[6]*1;i=x[7]*1;if(t>39&&i>4){v--}if((11-(3*x[1]+7*x[2]+6*x[3]+1*x[4]+8*x[5]+9*x[6]+4*x[7]+5*x[8]+2*x[9])%11)%11===x[10]*1&&(11-(5*x[1]+4*x[2]+3*x[3]+2*x[4]+7*x[5]+6*x[6]+5*x[7]+4*x[8]+3*x[9]+2*x[10])%11)%11===x[11]*1){v++}alert(Math.floor(v/3))
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.