Il conto alla rovescia della giornata lavorativa


17

Ho avuto un'idea geniale per semplificare la vita lavorativa: un conto alla rovescia per una data specifica che conta solo i giorni lavorativi.


L'attività di base è creare un conto alla rovescia per una data specifica che includa solo i giorni lavorativi nel conto alla rovescia.

Poiché la giornata lavorativa conta lunedì , martedì , mercoledì , giovedì e venerdì .

L'Input dovrebbe essere una data specifica nel formato standard europeo "non ufficiale" dd.MM.yyyye deve essere oggi o un giorno in futuro.

L'output dovrebbe essere solo il numero di giorni rimasti.

Essendo vince il codice più corto.


Caso di prova:

  Today    |   Input    | Output
10.12.2018 | 17.12.2018 |    5
02.10.2018 | 16.10.2018 |   10

Se ho perso alcune cose nella domanda, ti prego di perdonarmi - è la mia prima domanda :)

MODIFICARE:

  • Puoi usare falsecome output invece di 0 <- ma non è bello
  • Non è necessario rispettare l'ora legale

9
C'è qualche motivo specifico dietro questo formato di input europeo "non ufficiale" ? Il nostro consenso è di consentire input flessibili quando possibile.
Arnauld,

6
Ha davvero senso aggiungere la "sfida aggiuntiva" di un formato data difficile da elaborare? Sembra solo un linguaggio ingiusto che ha formati di date flessibili ...
Quintec,

3
@Hille non ho detto che era "difficile", è solo una seccatura inutile, soprattutto nel code-golf ... nota il link che Arnauld ha pubblicato sopra ... in genere l'input flessibile è la norma ...
Quintec

6
A proposito, noti che questa è la tua prima sfida; Ti invito a utilizzare The Sandbox per il perfezionamento prima di pubblicare una sfida su main! Altrimenti, bel lavoro, e mi divertirò a vedere qualcosa in più da te!
Giuseppe,

7
Non molto colpito dal rigoroso formato di input, ma a parte questo è una bella sfida.
ElPedro,

Risposte:


18

05AB1E , 130 128 133 131 124 123 byte

žežfžg)V0[Y`UÐ3‹12*+>13*5÷s3‹Xα©т%D4÷®т÷©4÷®·()ćsO7%2@+Y`т‰0Kθ4ÖUD2Qi\28X+ë<7%É31α}‹iY¬>0ëY1¾ǝDÅsD12‹i>1ë\1Dǝ¤>2}}ǝVYI'.¡Q#

Sono fuori di testa..

Per la lingua del golf 05AB1E non importa affatto se l'ingresso è . o -. Tuttavia, 05AB1E non ha alcun builtin per oggetti Date o calcoli. L'unica funzione incorporata relativa alle date che ha è l'anno / mese / giorno / ore / minuti / secondi / microsecondi di oggi.

Quindi, per questo motivo, quasi tutto il codice che vedi sono calcoli manuali per passare al giorno successivo e calcolare il giorno della settimana.

+5 byte a causa di una parte che ho dimenticato nella formula di Zeller (anno-1 per mesi gennaio e febbraio) ..

Provalo online o Provalo online con una data auto-specificata emulata di "oggi" .

Spiegazione:

Muro di testo in arrivo.

In generale, il codice segue il seguente pseudo-codice:

1   Date currentDate = today;
2   Integer counter = 0;
3   Start an infinite loop:
4*    If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):
5       Counter += 1;
6*    currentDate += 1; // Set currentDate to the next day in line
7     If(currentDate == parsed input-string):
8       Stop the infinite loop, and output the counter

1) Date currentDate = today;fa parte del programma 05AB1E:

že          # Push today's day
  žf        # Push today's month
    žg      # Push today's year
      )     # Wrap them into a single list
       V    # Pop and store this list in variable `Y`

2) Integer counter = 0;e 3) Start an infinite loop:sono semplici nel programma 05AB1E:

0     # Push 0 to the stack
 [    # Start an infinite loop

4) If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):è la prima parte difficile con calcoli manuali. Poiché 05AB1E non ha built-in Date, dovremo calcolare manualmente il giorno della settimana .

La formula generale per fare questo è:

h=(q+13(m+1)5+K+K4+J42J)mod7,

Dove per i mesi da marzo a dicembre:

  • q è laday del mese ([1, 31])
  • m è 1-indicizzatomonth ([3, 12])
  • K è l'anno del secolo (yearmod100 )
  • J è il secolo indicizzato 0 (year100)

E per i mesi gennaio e febbraio:

  • q è laday del mese ([1, 31])
  • m è 1-indicizzatomonth+12 ([13, 14])
  • K è l'anno del secolo per l'anno precedente ((year1)mod100 )
  • J è il secolo 0 indicizzato dell'anno precedente (year1100)

Risultato nel giorno della settimana h , dove 0 = sabato, 1 = domenica, ..., 6 = venerdì.
Fonte: congruenza di Zeller

Possiamo vederlo in questa parte del programma 05AB1E:

Y             # Push variable `Y`
 `            # Push the day, month, and year to the stack
  U           # Pop and save the year in variable `X`
   Ð          # Triplicate the month
    3        # Check if the month is below 3 (Jan. / Feb.),
              # resulting in 1 or 0 for truthy/falsey respectively
      12*     # Multiply this by 12 (either 0 or 12)
         +    # And add it to the month
              # This first part was to make Jan. / Feb. 13 and 14

>             # Month + 1
 13*          # Multiplied by 13
    5÷        # Integer-divided by 5
s3           # Check if the month is below 3 again (resulting in 1 / 0)
   Xα         # Take the absolute difference with the year
     ©        # Store this potentially modified year in the register
      т%      # mYear modulo-100
D4÷           # mYear modulo-100, integer-divided by 4
®т÷©4÷        # mYear integer-divided by 100, and then integer-divided by 4
®·(           # mYear integer-divided by 100, doubled, and then made negative
)             # Wrap the entire stack into a list
 ć            # Extract the head (the counter variable that was also on the stack)
  s           # Swap so the calculated values above are as list at the top
   O          # Take the sum of this entire list
    7%        # And then take modulo-7 to complete the formula,
              # resulting in 0 for Saturday, 1 for Sunday, and [2, 6] for [Monday, Friday]

2@            # Check if the day is greater than or equal to 2 (so a working day)

5) Counter += 1;è di nuovo semplice:

     # The >=2 check with `2@` results in either 1 for truthy and 0 for falsey
+    # So just adding it to the counter variable is enough

6) currentDate += 1; // Set currentDate to the next day in lineè ancora più complesso, perché dobbiamo farlo manualmente. Quindi questo verrà esteso al seguente pseudo-codice:

a   Integer isLeapYear = ...;
b   Integer daysInCurrentMonth = currentDate.month == 2 ?
c                                 28 + isLeapYear
d                                :
e                                 31 - (currentDate.month - 1) % 7 % 2;
f   If(currentDate.day < daysInCurrentMonth):
g     nextDate.day += 1;
h   Else:
i     nextDate.day = 1;
j     If(currentDate.month < 12):
k       nextDate.month += 1;
l     Else:
m       nextDate.month = 1;
n       nextDate.year += 1;

Fonti:
algoritmo per determinare se un anno è un anno bisestile. (EDIT: non più pertinente, poiché utilizzo un metodo alternativo per verificare gli anni bisestili che hanno consentito di risparmiare 7 byte.)
Algoritmo per determinare il numero di giorni in un mese.

6a) Integer isLeapYear = ...;viene fatto in questo modo nel programma 05AB1E:

Y             # Push variable `Y`
 `            # Push the days, month and year to the stack
  т‰          # Divmod the year by 100
    0K        # Remove all items "00" (or 0 when the year is below 100)
      θ       # Pop the list, and leave the last item
       4Ö     # Check if this number is visible by 4
         U    # Pop and save the result in variable `X`

Utilizzato anche in questa mia risposta 05AB1E , quindi vengono aggiunti alcuni anni di esempio per illustrare i passaggi.

6b) currentDate.month == 2 ?e 6c) 28 + isLeapYearsono fatti in questo modo:

D            # Duplicate the month that is now the top of the stack
 2Q          # Check if it's equal to 2
   i         # And if it is:
    \        #  Remove the duplicated month from the top of the stack
     28X+    #  Add 28 and variable `X` (the isLeapYear) together

6d) :e 6e) 31 - (currentDate.month - 1) % 7 % 2;sono fatti in questo modo:

ë           # Else:
 <          #  Month - 1
  7%        #  Modulo-7
    É       #  Is odd (shortcut for %2)
     31     #  Push 31
       α    #  Absolute difference between both
}           # Close the if-else

6f) If(currentDate.day < daysInCurrentMonth):è fatto in questo modo:

     # Check if the day that is still on the stack is smaller than the value calculated
 i    # And if it is:

6g) nextDate.day += 1;è fatto in questo modo:

Y       # Push variable `Y`
 ¬      # Push its head, the days (without popping the list `Y`)
  >     # Day + 1
   0    # Push index 0

        # (This part is done after the if-else clauses to save bytes)
}}      # Close the if-else clauses
  ǝ     # Insert the day + 1 at index 0 in the list `Y`
   V    # Pop and store the updated list in variable `Y` again

6h) Else:e 6i) nextDate.day = 1;vengono quindi eseguiti in questo modo:

ë        # Else:
 Y       #  Push variable `Y`
  1      #  Push a 1
   ¾     #  Push index 0
    ǝ    #  Insert 1 at index 0 (days part) in the list `Y`

6j) If(currentDate.month < 12)::

D           # Duplicate the list `Y`
 Ås         # Pop and push its middle (the month)
   D12     # Check if the month is below 12
       i    # And if it is:

6k) nextDate.month += 1;:

>       # Month + 1
 1      # Push index 1

        # (This part is done after the if-else clauses to save bytes)
}}      # Close the if-else clauses
  ǝ     # Insert the month + 1 at index 1 in the list `Y`
   V    # Pop and store the updated list in variable `Y` again

6l) Else:, 6m) nextDate.month = 1;e 6n) nextDate.year += 1;vengono quindi eseguiti in questo modo:

ë        # Else:
 \       #  Delete the top item on the stack (the duplicated month)
  1      #  Push 1
   D     #  Push index 1 (with a Duplicate)
    ǝ    #  Insert 1 at index 1 (month part) in the list `Y`

 ¤       #  Push its tail, the year (without popping the list `Y`)
  >      #  Year + 1
   2     #  Index 2

         # (This part is done after the if-else clauses to save bytes)
}}       # Close the if-else clauses
  ǝ      # Insert the year + 1 at index 2 in the list `Y`
   V     # Pop and store the updated list in variable `Y` again

E infine alle 8) If(currentDate == parsed input-string):e 9) Stop the infinite loop, and output the counter:

Y          # Push variable `Y`
 I         # Push the input
  '.¡     '# Split it on dots
     Q     # Check if the two lists are equal
      #    # And if they are equal: stop the infinite loop
           # (And output the top of the stack (the counter) implicitly)

5
Sei un pazzo ... abbi un voto.
AdmBorkBork,

1
Il programma 05AB1E più lungo di sempre?
Luis Mendo,

2
@LuisMendo Close, ma temo di avere una risposta 05AB1E che è ancora più lunga e una che arriva troppo vicino .. ;) Sono sicuro che sarò in grado di giocare a pochi byte qui e lì e semplificare parti dell'implementazione dello pseudo-codice del giorno successivo. Guarderà domani mattina, ma sono appena tornato dallo sport e andrà a letto presto.
Kevin Cruijssen,

11

Excel 24 byte

Presuppone l'immissione nella cella A1

=NETWORKDAYS(NOW()+1,A1)

Utilizza la funzione integrata. Purtroppo la funzione include sia oggi che la data di fine. Da allora OP ha chiarito di non contare oggi, quindi ne aggiungo uno ad ORA per non contarlo oggi.

Per rispondere ai commenti sul formato del numero, di nuovo, questo è lo standard Excel: inserisci qui la descrizione dell'immagine


Mentre funziona con i valori di data, non riesce a prendere l'input come indicato. Cioè (almeno nella versione USA) 10.12.2018è una stringa se tenuta in una cella piuttosto che una data. La soluzione più ovvia, ma a lungo per correggere questo sarebbe di cambiare A1a DATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))nella soluzione
Taylor Scott

sfortunatamente, la community ha deciso che le lingue devono essere eseguite con le loro impostazioni predefinite per essere valide (l'unica eccezione che ho visto è la lingua - IE, se la tua lingua supporta sia l'inglese che lo spagnolo, puoi prontamente usare l'una o l'altra, ma questo deve essere notato.) Inoltre, OP (@hille) non ha dichiarato che il formato è flessibile, e in effetti ha affermato il contrario (vedi il secondo commento su questa domanda)
Taylor Scott,

2
Il formato non è standard, è basato sulle impostazioni locali. Excel legge il formato dalla HKCU\Control Panel\International\sDecimalstringa di registro. Su un'installazione predefinita di Windows negli Stati Uniti che è MM / gg / aaaa. Nella maggior parte dei paesi dell'UE questo sarebbe il valore predefinito.
Erik Un

@luisMendo Sì, funziona. Non ho visto alcun chiarimento. Se invece non fosse stato conteggiato l'ultimo giorno, avrei potuto = NETWORKDAYS (NOW (), A1-1). Sapevo che sarebbe sempre stato lo stesso numero di byte, indipendentemente da quale chiarimento.
Keeta - ripristina Monica il

Sono contento che funzioni. Ho rimosso il downvote
Luis Mendo il


8

Java 10, 233 232 226 byte

import java.util.*;d->{int r=0;var s=Calendar.getInstance();s.setTime(new Date());var e=s.getInstance();for(e.setTime(new java.text.SimpleDateFormat("dd.MM.yyyy").parse(d));!s.after(e);s.add(5,1))if(s.get(7)%7>1)r++;return r;}

La data mi ricorda sempre quanto sia davvero prolisso Java.

NOTA: ora ci sono due risposte Java più brevi (inferiori a 175 byte), una con un uso intelligente dei metodi obsoleti rispetto alle precedenti versioni Java di @LukeStevens e una che utilizza la java.time.LocalDatenovità rispetto a Java 8 di @ OlivierGrégoire .

Provalo online.

Spiegazione:

import java.util.*;            // Required import for both Calendar and Date
d->{                           // Method with String parameter and integer return-type
  int r=0;                     //  Result-integer, starting at 0
  var s=Calendar.getInstance();//  Create a Calendar instance for the start-date
  s.setTime(new Date());       //  Set the start date to today
  var e=s.getInstance();       //  Create a Calendar instance for the end-date
  for(e.setTime(               //  Set the end date to:
        new java.text.SimpleDateFormat("dd.MM.yyyy")
                               //   Create a formatter for the "dd.MM.yyyy" format
         .parse(d));           //   And parse the input-String to a Date
      !s.after(e)              //  Loop as long as we haven't reached the end date yet
      ;                        //    After every iteration:
       s.add(5,1))             //     Increase the start-date by 1 day
    if(s.get(7)%7>1)           //   If the day of the week is NOT a Saturday or Sunday:
                               //   (SUNDAY = 1, MONDAY = 2, ..., SATURDAY = 7)
      r++;                     //    Increase the result-sum by 1
  return r;}                   //  Return the result-sum

Potresti farlo e=s.clone()?
Quintec,

1
Possiamo anche (suppongo) fare Calendar s=Calendar.getInstance(),e=s.getInstance(), che purtroppo finisce per essere esattamente della stessa lunghezza.
Misha Lavrov,

1
@MishaLavrov Ah, la statica in Ceffetti non è necessaria. Era da una vecchia parte del codice in cui ho usato anche Caltrove. Sono stato in grado di golf 1 byte utilizzando var s=Calendar.getInstance();var e=s.getInstance();così grazie. :)
Kevin Cruijssen,

1
150 byte , utilizzando java.time.
Olivier Grégoire,

1
Fatto! È molto vicino in byte all'altra risposta, ma non è ancora battuto.
Olivier Grégoire,

7

JavaScript (ES6), 116 103 byte

f=(d,n=+new Date)=>(D=new Date(n)).toJSON()<d.split`.`.reverse().join`-`&&(D.getDay()%6>0)+f(d,n+864e5)

Provalo online!

Come?

n .

nD.toJSON() metodo:

AAAA - MM - GG T hh : mm : ss.sss Z

YYYY-MM-DDdYYYY-MM-DDDD.MM.YYYY

d.split`.`.reverse().join`-`

D.getDay()0606

(D.getDay() % 6 > 0) + f(d, n + 864e5)

86,400,000n


6

MATL , 24 byte

46tQZt24&YO:Z':X-9XO83-z

Provalo online!

Non voglio avere alcun formato di input in modo che specifici linguaggi di golf del codice abbiano un grande vantaggio

Sei riuscito a metà :-)

Spiegazione

46      % Push 46 (ASCII for '.')
tQ      % Duplicate, add 1: gives 47 (ASCII for '/')
Zt      % Implicit input. Replace '.' by '/' in the input string
24&YO   % Convert string with date format 24 ('dd/mm/yyyy') to serial date number.
        % This is an integer representing day starting at Jan-1-0000
:       % Inclusive range from 1 to that
Z'      % Push current date and time as a serial number. Integer part is day;
        % decimal part represents time of the day
:       % Inclusive range from 1 to that
X-      % Set difference. Gives serial numbers of days after today, up to input
9XO     % Convert each number to date format 9, which is a letter for each day
        % of the week: 'M', 'T', 'W', 'T', ' F', 'S', 'S'
83-     % Subtract 83 (ASCII for 'S')
z       % Number of nonzeros. Implicit display

Se ho compreso correttamente la sfida, prendi solo un input di data e lo confronti con la data di oggi. Ad esempio, 16.10.2018oggi (lunedì 01-10-2018) risulterebbe 11, domani a 10, ecc.
Kevin Cruijssen,

@KevinCruijssen Whoops. Grazie! Corretto ora
Luis Mendo,

1
E con lo stesso numero di byte. :) Bello, +1 da parte mia.
Kevin Cruijssen,

6

Wolfram Language (Mathematica) , 64 56 byte

DayCount[Today,""<>#~StringTake~{{4,6},3,-4},"Weekday"]&

Provalo online!

DayCount[x,y,"Weekday"]conta il numero di giorni feriali tra xey .

Gli input xe ypossono essere molte cose, tra cui una fantasia DateObjectcome quella restituita Todayo una stringa nel formato (purtroppo)mm.dd.yyyy .

Il mio precedente tentativo ha cercato di trasformare l' dd.mm.yyyyingresso in aDateObject dicendo a Mathematica come analizzarlo; la nuova soluzione semplicemente riorganizza la stringa per mettere giorno e mese nell'ordine che Mathematica si aspetta.

Vale la pena notare che la soluzione a 28 byte DayCount[Today,#,"Weekday"]&non funziona perfettamente solo per un formato di input mese-giorno-anno, ma gestisce anche correttamente input univoci giorno-mese-anno come 31.12.2018, che non potrebbe significare "il 12 ° giorno del 31 ° mese". Quindi è corretto più del 60% delle volte :)



5

R, 72 caratteri

Una variazione sulla risposta fornita da @ngm che evita al grepl di salvare alcuni caratteri e funziona in locali non inglesi.

sum(strftime(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1),'%u')<6)+1


1
Più breve e anche più generale. Bella risposta e benvenuto in manicomio.
ngm

1
Benvenuti in PPCG! puoi aggiungere un link TIO - è facile e formatta la risposta per te :)
JayCe

5

Java (OpenJDK 8) , 174 166 165 byte

Con un po 'di ispirazione dalla risposta di Kevin e una buona vecchia rete da traino attraverso l'API Date obsoleta, sono riuscito a ottenere una soluzione Java più concisa.

-8 byte grazie all'inventiva analisi della data regex di Kevin

-1 byte grazie all'intelligente operazione bit per bit di Nevay

import java.util.*;d->{long r=0,s=new Date().getTime(),e=Date.parse(d.replaceAll("(..).(..).","$2/$1/"));for(;s<=e;s+=864e5)r-=-new Date(s).getDay()%6>>-1;return r;}

Provalo online!

Spiegazione

import java.util.*;                         // Required import for Date 
long r=0,                                   // Initialise result variable
     s=new Date().getTime(),                // Current date in millis
     e=Date.parse(
         d.replaceAll("(..).(..).","$2/$1/")// Use regex to convert to MM/dd/yyyy
     );                                     // Parse date arg using deprecated API
for(;s<=e;                                  // Loop while current millis are less than date arg (e.g. date is before)       
    s+=864e5)                               // Add 86400000 ms to current date (equiv of 1 day)
    r-=-new Date(s).getDay()%6>>-1;        // If day is Sunday (0) or Saturday (6) don't increment, else add 1
return r;                                   // When loop finished return result

1
Bella risposta! Uso intelligente di varargs con d=d[0].splite deprecato .parsecon il formato di MM/dd/yyyyformato predefinito . Un piccolo errore nel tuo post, hai import java.text.*;invece import java.util.*;nel tuo codice e // Required import for both Calendar and Datenella tua spiegazione (anche se non usi Calendar).
Kevin Cruijssen,

@KevinCruijssen Non ho idea del motivo per cui avevo java.textrisolto ora! Grazie!
Luke Stevens,

1
Anche se mi è piaciuto d=d[0].splitcon i varargs, cambiando l'input in una normale stringa, rimuovendo d=d[0].split("\\.");e cambiando d[1]+"/"+d[0]+"/"+d[2]per d.replaceAll("(..).(..).","$2/$1/") salvare 7 byte .
Kevin Cruijssen,

1
E 1 byte in più cambiando r+=new Date(s).getDay()%6<1?0:1,s+=864e5);in s+=864e5)r+=new Date(s).getDay()%6<1?0:1;. :)
Kevin Cruijssen,

1
-1 byte:r-=-new Date(s).getDay()%6>>-1;
Nevay,

4

Rosso , 72 byte

func[a][b: now/date s: 0 until[if b/weekday < 6[s: s + 1]a < b: b + 1]s]

Provalo online!

Prende la data nel formato gg-mm-aaaa, ad esempio 31-10-2018 (funziona anche con 10-ott-2018)

Input rigoroso:

Rosso , 97 byte

func[a][a: do replace/all a".""-"b: now/date s: 0 until[if b/weekday < 6[s: s + 1]a < b: b + 1]s]

Provalo online!

Bonus:

Restituisce un elenco delle date / giorni feriali dei giorni lavorativi fino alla data indicata:

Rosso , 235 byte

f: func [ a ] [
    b: now/date
    d: system/locale/days
    collect [ 
        until [ 
            if b/weekday < 6 [ 
                keep/only reduce [ b ":" d/(b/weekday) ]
            ]
            a < b: b + 1
        ]
    ]
]

Provalo online!


Eh, niente male, in pitone ho bisogno di spendere circa 72 byte per elaborare questo formato IO ...: P
Quintec,

1
Di solito le mie soluzioni Red sono tra le più lunghe, ma fortunatamente Red gestisce molto bene le date :)
Galen Ivanov

1
90 byte per elaborare Python ... ho finito, ho chiuso fino a quando non c'è un formato di input più flessibile: P
Quintec


3

Python 2 , 163 156 149 147 byte

lambda s:sum((date.today()+timedelta(x)).weekday()<5for x in range((date(*map(int,(s.split(".")[::-1])))-date.today()).days))
from datetime import*

Provalo online!

-7 grazie a @mypetlion

-7 in più grazie a @ovs

+30 a causa del formato di input molto restrittivo che ho notato solo prima di pubblicare il mio codice precedente che ha preso input come ad esempio (2018,11,1):-(


2
Non c'è bisogno di questo: (0,1)[t.weekday()<5]. I booleani Python sono una sottoclasse di inte True, Falsepossono essere utilizzati in operazioni aritmetiche come 1,0. Sostituirlo con c+=t.weekday()<5per salvare 7 byte.
mypetlion

1
149 byte come lambda.
Ovs

Grazie @mypetlion. Non avrei dovuto perdere quello.
ElPedro,

Grazie @ovs. La seconda volta hai aiutato di recente. L'ultima volta è stato un impressionante -30. Stavo cercando di capire come farlo entrare in una lambda.
ElPedro,

3

Java (JDK 10) , 171 byte

s->{int c=0;for(var t=java.time.LocalDate.now();!t.parse(s.replaceAll("(..).(..).(.*)","$3-$2-$1")).equals(t);t=t.plusDays(1))c-=t.getDayOfWeek().getValue()/6-1;return c;}

Provalo online!

Titoli di coda


1
È possibile modificare l' (.*)\\.(.*)\\.(.*)a (..).(..).(.*).
Kevin Cruijssen,

Con la tua replaceAlltecnica, tuttavia, la sua risposta può essere giocata a golf anche di 7 byte, quindi la tua è ancora leggermente più lunga. ;)
Kevin Cruijssen,

@KevinCruijssen Grazie per la regex! E non preoccuparti: non mi dispiace avere una risposta più lunga;)
Olivier Grégoire,

3

JavaScript (Node.js) , 168 160 139 133 byte

35 byte in meno grazie a Quintec e Kevin Cruijssen

D=>{var i=D.split('.'),n=0;for(var d=new Date();d<=new Date(i[2],i[1]-1,i[0]);d.setDate(d.getDate()+1))n+=-~d.getDay()%7>1;return n;}

Provalo online!

D=>{
  var i=D.split('.'),                 // Splits the date string by .
      n=0;                            // Counter variable
  for(var d=new Date();               // For the actual date
      d<=new Date(i[2],i[1]-1,i[0]);      // As long as the date is less or equal the requested date
      d.setDate(d.getDate()+1))           // Count the date one up
    n+=-~d.getDay()%7>1;                // If the date is not a Sunday or Saturday
  return n;                           // Return the counter variable
}

1
158 byte con lambda
Quintec,

1
139 byte con condizione if migliorata
Quintec

1
Poiché il metodo non è ricorsivo, non è necessario aggiungere il f=conteggio dei byte (e su TIO è possibile inserirlo nell'intestazione), motivo per cui @Quintec ha dichiarato che era 139 byte anziché 141 byte. Inoltre, è possibile modificare if((d.getDay()+1)%7>1)n++;per n+=-~d.getDay()%7>1;il golf a 133 byte .
Kevin Cruijssen,


1
Qualche consiglio in più per riferimenti futuri.
Shaggy,

3

Python3 e Numpy , 96 byte

Non potrei essere più piccolo della noiosa soluzione prefabbricata ...

from numpy import*
d=datetime64
lambda s:busday_count(d('today'),d(f'{s[6:]}-{s[3:5]}-{s[:2]}'))

Provalo online!


Deve entrare in Python 3;)
ElPedro

In base all'importazione, non stai usando Python 3 , ma piuttosto Python 3 con numpy .
Jonathan Frech,

@JonathanFrech dovrebbe essere nel titolo? altri che usano python hanno anche usato una libreria in quanto python non ha un tipo di dati incorporato per date o ore.
Aaron,

1
Questo dipende dalla tua definizione di builtin - moduli come datetime sono moduli di libreria standard e quindi li considero parte del linguaggio principale. Tuttavia, quando si utilizzano moduli di terze parti come numpy , si migliora le capacità della lingua e quindi la vedrei come un'altra lingua.
Jonathan Frech,

2

PowerShell , 107 99 byte

-8 byte grazie a mazzy

$d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5}$o

Provalo online!

Esegue una regex -splitsull'ingresso $args, memorizza i valori in $days, $mesi e $yorecchie, rispettivamente. Quindi, inserisce un forciclo, inizializzando $aalla data odierna. Il ciclo continua mentre $aè -lessenziale la tnostra data target di input. Ogni iterazione stiamo aggiungendo 1da ysa $a, e verificare se la corrente D*k(abbreviazione di DayOfWeek) è nel range 1..5(ad esempio, Lunedi a Venerdì). Quel risultato booleano viene accumulato $oe, una volta usciti dal ciclo, quel valore viene lasciato sulla pipeline e l'output è implicito.


100 byte? $d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5};$o
mazzy

1
@mazzy In effetti. Inoltre, il punto for(...){...}e virgola tra e $opuò essere rimosso, quindi ora siamo sotto i 100!
AdmBorkBork,

2

Python 2 , 147 143 141 140 byte

from datetime import*
lambda e,s=date.today():sum((s+timedelta(x+1)).weekday()<5for x in range((date(*map(int,e.split(".")[::-1]))-s).days))

Provalo online!

Accetta una stringa, e, che rappresenta la data di fine nel formato "gg.MM.AAAA". Facoltativamente, accetta anche la data di inizio, ma si prevede che sia una data datetime.

La data di inizio, s, è predefinita alla data odierna come oggetto datetime.date per ignorare l'ora. L'ora di fine viene analizzata in un oggetto datetime.datetime, quindi convertita in una data, poiché gli oggetti datetime.date non hanno un metodo di analisi e gli orari non possono essere aggiunti / sottratti dalle date. Scorre ogni giorno tra (inizio, fine] e aggiunge 1 al totale se il numero del giorno della settimana è <5. ([0-4] sono [Lun-Ven], [5-6] sono [Sab-Dom]).

L'analisi del datetime è la cosa peggiore, ragazzi.

EDIT: rubato ElPedro della mappa di (int, cosa) per salvare 4 byte.

EDIT 2: BOOGALOO ELETTRICO: salvato 2 byte rendendolo una funzione anonima. (Grazie Aaron!)

EDIT 3: xrange -> range. (Grazie ancora Aaron!)


1
Prego! Bella risposta :)
ElPedro

1
È una convenzione che puoi lasciare fuori f=dalle espressioni lambda qui
Aaron,

1
"L'analisi del datetime è la peggiore, ragazzi" Hahahaha sento il mio dolore, ci siete riusciti dove ho fallito però: P
Quintec,

@Aaron Non sono mai sicuro che vada bene con più funzioni o con dichiarazioni di importazione, grazie!
Triggernometria

1
Puoi anche usare rangepiuttosto che xrangedovrebbe funzionare ancora bene.
Aaron

2

PHP, 66 byte

for($t=time();$t<strtotime($argn);)$r+=date(N,$t+=86400)<6;echo$r;

uscita vuota per 0; inserire +tra echoe $rper correggere.

Esegui come pipe -nro provalo online .


60 byte con output unario:

for($t=time();$t<strtotime($argn);)echo date(N,$t+=86400)<6;

1

PHP (con carbonio ), 107 byte

function a($d){return Carbon\Carbon::parse($d)->diffInDaysFiltered(function($e){return!$e->isWeekend();});}

1

Formula IBM / Lotus Notes - 99 byte

d:=i;c:=0;@While(d>@Today;@Set("c";c+@If(@Weekday(d)=1:7;0;1));@Set("d";@Adjust(d;0;0;-1;0;0;0)));c

Accetta input da un campo data / ora i. Il formato di input di iè impostato su .separato quindi non è necessario convertire l'input. Le note possono prendere un input di data con qualsiasi separatore, purché tu lo dica prima di quello che sarà (spero che non sia barare!). La formula è nel campo numerico calcolatoo sullo stesso modulo.

Interessante a parte: da allora @Fore @Whilesono stato introdotto nel linguaggio Formula in (credo) R6 dal grande Damien Katz, l'unico uso che ho trovato per loro è il golf del codice. Non li ho mai usati in un'app di produzione.

Non esiste un TIO disponibile per la formula, quindi ecco uno screenshot fatto il 02.10.2018:

enter image description here



1

K4 , 40 byte

Soluzione:

{+/1<.q.mod[d+!(."."/:|"."\:x)-d:.z.d]7}

Spiegazione:

Calcola la differenza tra le date, usa il modulo 7 per ignorare i fine settimana, riassumi.

{+/1<.q.mod[d+!(."."/:|"."\:x)-d:.z.d]7} / the solution
     .q.mod[                         ]7  / modulo with 7
                                 .z.d    / UTC date
                               d:        / save as d
                              -          / subtract from
               (             )           / do this together
                       "."\:x            / split input on "."
                      |                  / reverse
                 "."/:                   / join back with "."
                .                        / take the value
              !                          / range 0..the difference
            d+                           / add today's date to range
   1<                                    / is 1 less than the modulo (ie is this mon-fri)?
 +/                                      / sum up

Appunti:

  • stesso byte alternativo all'analisi della data: "D"$,/|"."\:x

1

C (clang) , 209 208 205 byte

Flag del compilatore -DU=u=localtime(&b) -DW=tm_wday -DY=tm_year -DT=tm_yday(52 byte).

#import<time.h>
i;f(char*a){long b;struct tm t,*u;time(&b);U;strptime(a,"%d.%m.%Y",&t);for(i=0;u->T^t.T|u->Y^t.Y;u->W&&u->W^6&&i++,b+=86400,U);return i;}

Provalo online!

-1 byte grazie a @JonathanFrech


?i++:0-> &&++i.
Jonathan Frech,

0

q, 52 79 byte

{x:"D"$"."sv reverse"."vs x;i:0;while[x-.z.d;$[2>x mod 7;x-:1;[i+:1;x-:1]]];:i}

in q, ogni data ha un valore intero sottostante, basato su quanti giorni sono trascorsi dall'inizio del millennio. Applicando 'mod 7' a questo, si ottengono valori univoci per ogni giorno della settimana (0 per sabato, 6 per venerdì). Quindi, quando 2> x mod 7, non incrementare il contatore, per evitare il conteggio dei fine settimana.

EDIT: formato data rigoroso perso, modifica

EDIT2: incluso


1
Best I've come up with is {sum 1<mod[d+til("D"$x 10 vs 67893401)-d:.z.d]7} for 48 bytes without resorting to K verbs.
streetster

Using the list indices is a lot more elegant than reverse, and rather than using a loop, applying mod to the list. Great answer +1
Thaufeki
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.