IBM DFSORT, 11 3 righe di 71, 72 o 80 caratteri
OPTION COPY
OUTFIL REPEAT=12,OVERLAY=(5:SEQNUM,2,ZD,5,2,1,8,Y4T,LASTDAYM,TOJUL=Y4T*
,9,7,Y4T,ADDDAYS,+1,TOJUL=Y4T,1:16,7,Y4T,PREVDSUN,TOGREG=Y4T(-),12X)
Le due risposte con formato di uscita colonnare hanno superato la prova del tempo. Questo mi dà un "loop", una specie di, in quello su OUTFIL REPEAT = copia il record corrente più volte.
Tecnica diversa per arrivare al valore, che sembra più lungo ma più breve in quanto non riesco a trovare un modo incondizionato per gestire il 12 ° disco nell'anno successivo, e renderlo condizionato significa includere IFTHEN=(WHEN=
, due volte, e altre cose. Guadagnare sulle altalene (il primo del mese è il modo più semplice per farlo) perdere pesantemente sulle rotatorie (particolari requisiti di sintassi).
Questo utilizza una funzione integrata (tutte le funzioni in DFSORT sono integrate) per trovare l'ultimo giorno del mese. Quindi aggiunge un giorno (funzione) per arrivare al primo del mese successivo e utilizza la funzione PREVDSUN per ottenere la domenica precedente (che sarà sempre l'ultima domenica del mese precedente, come prima).
Quando si trasforma l'anno (immissione) in una data valida, viene utilizzato un numero progressivo a due cifre per il mese e quel valore viene copiato anche per il giorno, poiché il punto di partenza non ha importanza per il tempo in cui siamo validi dopo l'ultimo giorno del mese inizialmente: 5,2
è più breve di C'01'
.
Ecco il dettaglio:
OPZIONE COPIA: copia il file di input nell'output
OUTFIL: per consentire più file di output, con selezione e formattazione diverse, produrre report formattati. Usato preferibilmente al più corto a INREC
causa dell'uso di REPEAT=
.
REPEAT = 12: produce 12 copie di ciascun record. In questo esempio, può esserci un solo record di input (a differenza della versione precedente) a causa di SEQNUM.
5: - inizia dalla colonna 5 del record.
SEQNUM, 2, ZD - numero progressivo, l'impostazione predefinita inizia con una, due cifre, "decimale suddiviso in zone" (per i segni senza segno, che saranno, uguale al carattere).
1,8 - copia i byte 1 per la lunghezza 8 nella posizione corrente (9). Questo perché Y4T deve vedere che 8, altrimenti verrà utilizzato un formato data diverso.
Y4T - data in formato ccyymmdd (a causa dell'8 immediatamente davanti ad esso).
LASTDAYM - Ultimo giorno del mese (anche possibile di settimana, trimestre e anno).
TOJUL = - output della conversione della data per le funzioni della data (TOJUL è un carattere in meno di TOGREG)
9,7 - ora che è lungo 7, Y4T sarà CCYYDDD.
ADDDAYS - aggiunge un numero di giorni, adattandosi automaticamente se si passa al mese / anno successivo (potrebbe anche essere ADDMONS e ADDYEARS)
PREVDSUN - arriva la data giuliana, si trova la domenica precedente, TOGREG per ottenere il formato di output corretto, con il separatore "-" (potrebbe essere qualcosa che ti piace come separatore)
12X - spazi vuoti per chiarire il casino che ci ha permesso di farlo in un modo così breve
L'output di cui sopra, per il 2014, è:
2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-23
2014-12-28
È necessario qualcosa per dire al SORT cosa fare. Non esiste alcun valore predefinito. OPTION COPY
è il più corto, SORT FIELDS=COPY
è equivalente ma più lungo.
Il lavoro stesso è stato svolto questa volta OUTFIL
(per consentire l'uso di REPEAT). Il codice di lavoro è probabilmente uno di 160 (2 * 80), 144 (2 * 72), 140 (72 + 69) o 138 (70 + 68) (esclusi gli spazi vuoti iniziali, la continuazione forzata e gli spazi vuoti finali).
Dato che il ricevitore dovrebbe sapere cosa stanno facendo, penso di poter dire che il codice DFSORT elenca l'ultima domenica di ogni mese per qualsiasi anno dal 1900 (funzionerà dall'anno 0001, ma sto evitando la ricerca come bene) fino a 9999 (sebbene DFSORT supporti anni fino a 9999, la soluzione precedente non funzionerebbe nell'anno 9999 poiché la dodicesima data va nell'anno successivo) può essere twittata.
Perché il codice è così lungo, se ci sono funzioni incorporate particolarmente adatte?
Le definizioni dei campi sono effimere. Un campo è definito solo come una posizione particolare all'interno dei dati (che è un record) per il suo uso immediato. Per dirla in altro modo, i campi non sono definiti come tali, ma sono definiti per ogni utilizzo e solo per l'uso. Le funzioni di data devono sapere quali (di molti) formati di data sono utilizzati per l'origine e l'output deve essere in un formato di data, quindi deve essere specificato.
Ora che abbiamo un appuntamento giuliano ... TBC?
OPTION COPY
INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8*
,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,14:C'3',22:C'4',30:C'5',38:C'6',*
46:C'7',54:C'8',62:C'9',69:C'10',77:C'11',85:C'12',127:X,89,8,Y4T,PREV*
DSUN,TOGREG=Y4T(-),116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),105:X,73,8,Y4*
T,PREVDSUN,TOGREG=Y4T(-),94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),83:X,57,*
8,Y4T,PREVDSUN,TOGREG=Y4T(-),72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),61:X*
,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),*
39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T*
(-),17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),1:1,8,Y4T,PREVDSUN,TOGREG=Y4T*
(-),11:X,18,120,6X)
Ne ha bisogno JCL
//LASTSUNG EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
E un file di input (un'altra riga di JCL e tre elementi di dati instream):
//SORTIN DD *
2014
1900
2000
produce:
2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28
1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30
2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31
Funzionerà effettivamente fino all'anno 9999.
DFSORT è il prodotto di ordinamento Mainframe di IBM. I dati possono essere manipolati, ma poiché l'ordinamento è fondamentale e gli ordinamenti sono spesso di grandi dimensioni e di lunga durata, le schede di controllo DFSORT non hanno costrutti di loop, quindi non possiamo mettere un SORT in un loop. Rende le cose un po 'complicate per attività come il golf.
Perché pubblicare la risposta, è perché DFSORT ha una PREVDday
funzione. Quindi la scorsa domenica di un mese è facile. È la domenica precedente (PREVDSUN) al primo giorno del mese successivo.
È stato anche divertente farlo all'interno di un "operando" (OVERLAY), un po 'come fare tutto all'interno sprintf
o simile.
Qui è ungolfed:
OPTION COPY
INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,
1,8,1,8,1,8,1,8,
1,8,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,
14:C'3',22:C'4',30:C'5',38:C'6',46:C'7',54:C'8',
62:C'9',69:C'10',77:C'11',85:C'12',
127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
105:X,73,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
83:X,57,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
61:X,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
1:1,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
11:X,18,120,6X)
Sebbene non sia del tutto un abuso, non sarebbe normale tentare di stipare tutto questo in un OVERLAY, e ci sono alcune cose apparentemente non necessarie che sono necessarie per consentire a tutto di andare in un OVERLAY. C'è un po 'di spazio per giocare a golf, ma dal momento che eliminerebbe solo una linea al massimo, non sono tentato.
L'INREC viene elaborato per ciascun record.
OVERLAY consente di modificare il contenuto di un record esistente. Se il record viene esteso oltre la sua lunghezza nel processo, questo non è un problema.
1,4 è l'anno in arrivo. Ha un letterale di 0201 aggiunto ad esso, e quindi i successivi 1,8 lo ripetono 11 volte per dare un lungo mandrino di 96 byte,
Al dodicesimo anno del record corrente esteso viene aggiunto 1 e il suo mese è stato portato a 1 (gennaio).
I restanti 10 mesi vengono cambiati da 3 a 11.
Poi ci sono 12, in ordine inverso (a causa di OVERLAY) di questo tipo di cose:
127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
Il n: è un numero di colonna nel record. La X inserisce uno spazio. 89,8 prende i dati da quella colonna / lunghezza, Y4T li considera come una data CCYYMMDD, PREVDSUM elabora la domenica precedente, TOGREG = Y4T (-) li emette come una data CCYY-MM-DD gregoriana.
Poiché si ottiene spazzatura se l'origine e il target di una parte particolare di un OVERLAY si sovrappongono in modo distruttivo, gli ultimi si 11:X,18,120,6X)
riorganizzano e mascherano un po 'di casino.
Manuali e documenti sono disponibili all'indirizzo: http://www-01.ibm.com/support/docview.wss?uid=isg3T7000080 e include la Guida alla programmazione dell'applicazione DFSORT di oltre 900 pagine.
Come per tutti i prodotti IBM, tutti i manuali sono disponibili gratuitamente (tranne una quantità estremamente piccola di quelli molto costosi che solo un numero molto piccolo di persone al mondo pretenderebbe di capire).
Tutte le carte di controllo DFSORT devono iniziare con uno spazio vuoto. La colonna 72 viene utilizzata solo per la continuazione (qualsiasi operazione non vuota lo farà, ma * è convenzionale). La colonna 72 è seguita da un'area del numero di sequenza che viene ignorata, rendendo ogni record 80 byte.
Un'altra coppia di soluzioni a venire, forse.