Calcolo degli slot totali


17

Dato un elenco di lavori, che devono essere eseguiti in ordine, ciascuno con uno slot da fare, quanto tempo ci vorrà per eseguirli tutti se dopo aver fatto un lavoro lo stesso lavoro non può essere fatto per i prossimi due slot (raffreddamento degli slot )? Tuttavia, un lavoro diverso può essere assegnato in questo slot di raffreddamento.

Per esempio,

[9,10,9,8] => output: 5

Perché i lavori verranno assegnati come [9 10 _ 9 8].
1. Innanzitutto, 9 necessita di due punti di raffreddamento _ _. Quindi iniziamo con 9 _ _.
2. Il prossimo lavoro 10 è diverso dal precedente 9, quindi possiamo assegnare uno di _ _. Quindi avremo 9 10 _.
3. In terzo luogo, 9 non può essere assegnato ora, poiché il primo lavoro 9 è lo stesso lavoro e necessita di tempo di raffreddamento. 9 10 _ 9.
4. Infine, 8 non è uguale agli altri due lavori precedenti, quindi può essere assegnato subito dopo 9 e poiché si tratta dell'ultimo lavoro, non è necessario il tempo di raffreddamento. L'elenco finale è 9 10 _ 9 8e l'output previsto è 5, ovvero il numero di spot (o il numero di slot)

Casi test:

[1,2,3,4,5,6,7,8,9,10] => output : 10 ([1 2 3 4 5 6 7 8 9 10])
[1,1,1] => output: 7 ([1 _ _ 1 _ _ 1])
[3,4,4,3] => output: 6 ([3 4 _ _ 4 3])
[3,4,5,3] => output: 4 ([3 4 5 3])
[3,4,3,4] => output : 5 ([3 4 _ 3 4])
[3,3,4,4] => output : 8 ([3 _ _ 3 4 _ _ 4])
[3,3,4,3] => output : 7 ([3 _ _ 3 4 _ 3])
[3,2,1,3,-4] => output : 5 ([3 2 1 3 -4])
[] => output : 0 ([])
[-1,-1] => output : 4 ([-1 _ _ -1])

Il valore di input può essere qualsiasi numero intero (negativo, 0, positivo). La lunghezza dell'elenco lavori è 0 <= lunghezza <= 1.000.000.
L'output sarà un numero intero, il numero totale di slot, indicato nel test case come output. L'elenco tra parentesi indica come verrà generato l'output.

Criterio vincente


Va bene se non produciamo nulla anziché 0 per []?
wastl

8
Non è un po 'presto per accettare una risposta?
Nick Kennedy,

7
Come ha detto @NickKennedy, è troppo, troppo presto per accettare una soluzione. Alcuni addirittura consigliano di non accettare mai una soluzione.
Shaggy,

Risposte:



5

05AB1E , 22 byte

v¯R¬yQiõˆ}2£yåiˆ}yˆ}¯g

Provalo online o verifica tutti i casi di test .

Spiegazione:

v           # Loop over the integers `y` of the (implicit) input-list:
 ¯R         #  Push the global_array, and reverse it
   ¬        #  Get the first item (without popping the reversed global_array itself)
    yQi  }  #  If it's equal to the integer `y`:
       õˆ   #   Add an empty string to the global_array
   2£       #  Then only leave the first 2 items of the reversed global_array
     yåi }  #  If the integer `y` is in these first 2 items:
        ˆ   #   Add the (implicit) input-list to the global_array
 yˆ         #  And push the integer `y` itself to the global_array
g         # After the loop: push the global array, and then pop and push its length
            # (which is output implicitly as result)

Qual è l'area globale? È vuoto all'avvio del programma?
Incarnazione dell'ignoranza il

@EmbodimentofIgnorance Sì, è un singolo array a cui posso aggiungere qualcosa, che posso spingere e che posso cancellare. E infatti inizia inizialmente a vuoto.
Kevin Cruijssen il

3

Brachylog , 10 byte

È sempre bello vedere il problema in cui Brachylog funziona meglio

⊆Is₃ᶠ≠ᵐ∧Il

Spiegazione

⊆I           # Find the minimal ordered superset of the input (and store in I) where:
   s₃ᶠ       #     each substring of length 3
      ≠ᵐ     #     has only distinct numbers
        ∧Il  # and output the length of that superset

Provalo online!


2

R , 123 byte

`-`=nchar;x=scan(,'');while(x!=(y=gsub("([^,]+),(([^,]*,){0,1})\\1(,|$)","\\1,\\2,\\1\\4",x)))x=y;-gsub("[^,]","",y)+(-y>1)

Provalo online - programma singolo!

Provalo online - più esempi!

Un programma completo che legge un elenco di numeri interi separati da virgola come input e genera gli slot necessari. Sono sicuro che questo potrebbe essere ulteriormente risolto, e l'implementazione di questa soluzione basata su regex in alcune altre lingue sarebbe più efficiente in byte.

Nota sul secondo TIO l'ho racchiuso in una funzione per consentire la visualizzazione di più esempi. Questa funzione mostra anche l'elenco finale, ma questo non viene emesso dal mio programma principale se eseguito in modo isolato.


2

Query TSQL, 158 byte

Immettere i dati come tabella.

La query è ricorsiva quindi

OPZIONE (MAXRECURSION 0)

è necessario, poiché l'elenco dei numeri può superare 100 sebbene possa gestire solo 32.767 ricorsioni - la limitazione è davvero necessaria in questo compito?

DECLARE @ table(a int, r int identity(1,1))
INSERT @ VALUES(3),(3),(4),(4);

WITH k as(SELECT null b,null c,1p
UNION ALL
SELECT iif(a in(b,c),null,a),b,p+iif(a in(b,c),0,1)FROM @,k
WHERE p=r)SELECT sum(1)-1FROM k
OPTION(MAXRECURSION 0) 

Provalo online


2

R , 81 70 byte

sum(l<-rle(s<-scan())$l*3-3,1-l%/%6,((r=rle(diff(s,2)))$l+1)%/%2*!r$v)

Provalo online!

Dopo diversi tentativi falliti, il codice è diventato piuttosto brutto e non così breve, ma almeno ora funziona ...

Innanzitutto, valutiamo le lunghezze delle esecuzioni consecutive dello stesso lavoro. Ad esempio per 3, 3, 4, 3questo dà:

Run Length Encoding
  lengths: int [1:3] 2 1 1
  values : num [1:3] 3 4 3

Ognuna di queste corse produce (len - 1) * 3 + 1passaggi (+ 1 viene gestita separatamente).

Successivamente, elaboriamo le occorrenze dello stesso lavoro distanti 2 posti, come x, y, x:, utilizzando diff(s, lag=2). Il vettore risultante viene anche suddiviso in sequenze consecutive ( r) per rlefunzione. Ora, a causa delle varie alternanze intercalate, dobbiamo aggiungereceiling(r$len/2) passaggi per tutte le serie di zero. Per esempio:

x y x(lunghezza 1) e x y x y(lunghezza 2) richiedono entrambi 1 passaggio aggiuntivo:x y _ x (y)

x y x y x(lunghezza 3) e x y x y x y(lunghezza 4) richiedono entrambi 2 passaggi aggiuntivi:x y _ x y _ x (y)

Infine, dobbiamo compensare le occorrenze di queste alternanze nel bel mezzo di un lungo periodo dello stesso lavoro x, x, x, x...:, quindi 1-l%/%6anziché semplicemente 1.


Ero nel bel mezzo di commentare l'utilizzo diff(s,lag=2)per rilevare la prossimità! Ora sei un byte più corto della mia soluzione ...
Giuseppe

Sì, non mollare ancora :) Ora provo a sbarazzarmi di alcune parentesi ...
Kirill L.

2

Python 2 , 67 byte

r=[]
for x in input():
 while x in r[-2:]:r+=r,
 r+=x,
print len(r)

Provalo online!

Implementa la sfida piuttosto letteralmente. Utilizza copie dell'elenco stesso come "spazi vuoti", poiché questi non possono eguagliare alcun numero.


2

Carbone , 27 23 byte

Fθ«W№✂υ±²¦¦¦ι⊞υω⊞υι»ILυ

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

Fθ«

Passa sopra i lavori.

W№✂υ±²¦¦¦ι⊞υω

Aggiungi punti di raffreddamento mentre il lavoro è uno degli ultimi due nel risultato.

⊞υι»

Aggiungi il lavoro corrente al risultato.

ILυ

Stampa il numero di punti.


2

R , 74 68 byte

length(Reduce(function(x,y)c(y,rep("",match(y,x[2:1],0)),x),scan()))

Provalo online!

Costruisce l'array di lavoro (al contrario), quindi prende la lunghezza. Solo un po ' più breve della risposta di Kirill L. , quindi a volte l'approccio ingenuo è abbastanza buono. EDIT: ancora più corto! Ho anche preso in prestito il modello di test di Kirill.

-6 byte in sostituzione max(0,which(y==x[2:1])) di match(y,x,0) .


@Giuspeppe cosa fa la cfunzione?
Incarnazione dell'ignoranza il

@EmbodimentofIgnorance - csta per combine, anche se concatenatepotrebbe essere migliore; esso combina i suoi argomenti in un unico elenco.
Giuseppe,

Grazie, ho pensato che fosse strano che un linguaggio non progettato per il golf avrebbe avuto una funzione in una lettera
Embodiment of Ignorance,

1

Perl 6 , 98 byte

{($!=$,|$_ Z$_ Z .[1..*+1])>>.repeated.squish(:with({$+^=[*] $! ne$^a ne$^b,$b==($!=$a)})).sum+$_}

Provalo online!

Blergh, deve esserci un modo migliore per farlo. Non sono sicuro al 100% che questo sia del tutto corretto, anche se passa tutti i casi limite che mi vengono in mente.

Fondamentalmente, questo inizia raggruppando tutte le terzine dell'elenco di input, con il riempimento su entrambi i lati. Ad esempio, [1,2,1,2]diventa (Any,1,2), (1,2,1), (2,1,2), (1,2,Nil). Otteniamo gli repeatedelementi in ogni tripletta, diventando (), (1), (2), ().

Quindi squishsono elementi consecutivi che non sono la stessa lista, ma hanno le stesse dimensioni (per non schiacciare qualcosa di simile [1,1,1]), e il primo elemento non è uguale all'elemento precedente (perché non possiamo unire le ore [1,1,2,2]), e infine l'elemento prima non è stato anche squished ( [1,2,1,2,1,2]). Quindi (1), (2)nell'esempio sopra riportato verrebbe schiacciato insieme.

Infine, otteniamo le sumlunghezze di questo elenco, che rappresentano le nostre ore inserite, e aggiungiamo la lunghezza dell'elenco originale.

Per esempio:

(1,1,1) => (Any,1,1),(1,1,1),(1,1,Nil) => (1),(1,1),(1) => (no squishes) => 4+3 = 7
(1,2,1,2,1,2) => (Any,1,2), (1,2,1), (2,1,2), (1,2,1), (2,1,2), (1,2,Nil) => (),(1),(2),(1),(2),() => squish (1),(2) and (1),(2) => 2+6 = 8

1

JavaScript (ES6), 57 byte

f=([x,...a],p,q)=>1/x?1+f(x!=p&x!=q?a:[x,...a,x=f],x,p):0

Provalo online!

Commentate

f = (             // f is a recursive function taking:
  [x,             //   x   = next job
      ...a],      //   a[] = array of remaining jobs
  p,              //   p   = previous job, initially undefined
  q               //   q   = penultimate job, initially undefined
) =>              //
  1 / x ?         // if x is defined and numeric:
    1 +           //   add 1 to the grand total
    f(            //   and do a recursive call to f:
      x != p &    //     if x is different from the previous job
      x != q ?    //     and different from the penultimate job:
        a         //       just pass the remaining jobs
      :           //     else:
        [ x,      //       pass x, which can't be assigned yet
          ...a,   //       pass the remaining jobs
          x = f   //       set x to a non-numeric value
        ],        //
      x,          //     previous job = x
      p           //     penultimate job = previous job
    )             //   end of recursive call
  :               // else:
    0             //   stop recursion

1

C (gcc) , 69 byte

f(j,l)int*j;{j=l>1?(*j-*++j?j[-1]==j[l>2]?j++,l--,3:1:3)+f(j,l-1):l;}

Provalo online!

Ricorsione semplice.

f(j,l)int*j;{               //Jobs, (array) Length
    j=l>1                   //if l > 1, do a recursion:
        ? (*j-*++j          // check if first and second elements are equal (j++)
            ? j[-1]==       //  1st!=2nd; check if first and third are equal
                j[l>2]      //  (first and second if l==2, but we already know 1st!=2nd)
                ? j++,l--,3 //   1st==3rd (j++,l--) return 3+f(j+2,l-2)
                : 1         //   1st!=3rd (or l==2) return 1+f(j+1,l-1)
            : 3             //  1st==2nd            return 3+f(j+1,l-1)
          )+f(j,l-1)        // j and l were modified as needed
        : l;                // nothing more needed  return l
}


1

Smalltalk, 125 byte

c:=0.n:=q size.1to:n-2do:[:i|(j:=q at:i)=(k:=q at:i+1)ifTrue:[c:=c+2].j=(m:=q at:i+2)ifTrue:[c:=c+1]].k=m ifTrue:[c:=c+1].c+n

Spiegazione

c : accumulator of proximity penalty
q : input array.
n := q length
i : iteration index from 1 to: n-2 (arrays are 1-based in Smalltalk).
j := memory for element i, saves some few bytes when reused
k := similar to j but for i+1.
m := similar to k but for i+2.

Non è uno snippet ?
attinat


0

Lotto, 184 byte

@echo off
@set l=-
@set p=-
@set n=0
@for %%j in (%*)do @call:c %%j
@exit/b%n%
:c
@if %1==%l% (set l=-&set/an+=2)else if %1==%p% set l=-&set/an+=1
@set p=%l%&set l=%1&set/an+=1

L'input avviene tramite argomenti da riga di comando e l'output avviene tramite codice di uscita. Spiegazione:

@set l=-
@set p=-

Tieni traccia degli ultimi due lavori.

@set n=0

Inizializza il conteggio.

@for %%j in (%*)do @call:c %%j

Elabora ogni lavoro.

@exit/b%n%

Emette il conteggio finale.

:c

Per ogni lavoro:

@if %1==%l% (set l=-&set/an+=2)else if %1==%p% set l=-&set/an+=1

Se il processo è stato elaborato di recente, aggiungere un numero appropriato di punti di raffreddamento. Inoltre, cancellare l'ultimo lavoro in modo che il lavoro successivo inneschi il raffreddamento solo se è lo stesso di questo lavoro.

@set p=%l%&set l=%1&set/an+=1

Aggiorna gli ultimi due lavori e assegna un posto a questo lavoro.


0

Rapido, 114 byte

func t(a:[Int]){
var s=1
for i in 1...a.count-1{s = a[i-1]==a[i] ? s+3:i>1&&a[i-2]==a[i] ? s+2:s+1}
print("\(s)")}

Provalo online!


2
Non riesce 3,4,3,4, dovrebbe puntare 5, non 6.
Kirill L.

Oltre alla correzione xyxy @KirillL. notato, s = apuò essere s=a, e puoi fare s+=piuttosto che moltiplicare s=s+...e rimuovere gli spazi dopo ?: for i in 1...a.count-1{s+=a[i-1]==a[i] ?3:i>1&&a[i-2]==a[i] ?2:1}per salvare 9 byte.
Daniel Widdis,

0

Python 3 , 79 75 byte

-3 byte grazie a mypetlion
-1 byte grazie a Sara J

f=lambda a,b=[]:a and f(*[a[1:],a,a[:1]+b,[b]+b][a[0]in b[:2]::2])or len(b)

Provalo online!


1
a[0]in b[:2]and f(a,['']+b)or f(a[1:],[a[0]]+b)può diventare f(*[a[1:],a,[a[0]]+b,['']+b][a[0]in b[:2]::2])per salvare 2 byte.
mypetlion il

1
[a[0]]+bpuò diventare a[:1]+bper salvare 1 byte.
mypetlion il

1
Sostituire ['']+bcon [b]+bsalva un byte - bè un elenco, quindi non sarà mai uguale a nessuno dei valori ina
Sara J

0

Java (JDK) , 110 byte

j->{int p,q;for(p=q=j.length;p-->1;q+=j[p]==j[p-1]?2:(p>1&&j[p]==j[p-2]&(p<3||j[p-1]!=j[p-3]))?1:0);return q;}

Provalo online!

Codice non commentato commentato:

j -> {
    int p, q = j.length; // Run all jobs
    for (p = q; p-- > 1;) { // reverse iterate
        q += j[p] == j[p - 1] ? 2 : // add 2 if prev same
        (p > 1 && j[p] == j[p - 2] & // 1 if 2prev same
        (p < 3 || j[p - 1] != j[p - 3]) // except already done
        ) ? 1 : 0; // otherwise 0
    }
    return q;
}

Non funziona per 3,4,3,4,3,4, restituisce 7 anziché 8
Incarnazione dell'ignoranza

Questo è un piccolo problema malvagio.
Daniel Widdis,

0

Gelatina , 20 byte

ṫ-i⁹⁶x;
⁶;ç³Ṫ¤¥¥³¿L’

Provalo online!

Anche se questo è piuttosto simile alla risposta più breve di @EriktheOutgolfer , l'ho scritto senza vedere la sua. In ogni caso il suo è meglio!

Spiegazione

Collegamento diadico helper, prende l'elenco corrente come elemento a sinistra e l'elemento successivo come a destra

ṫ-            | take the last two items in the list
  i⁹          | find the index of the new item
    ⁶x        | that many space characters
      ;       | prepend to new item

Collegamento monadico principale, prende come elenco un numero intero

⁶             | start with a single space
 ;            | append...
  ç³Ṫ¤¥       | the helper link called with the current list
              | as left item and the next input item as right
       ¥³¿    | loop the last two as a dyad until the input is empty
          L   | take the length
           ’  | subtract one for the original space




0

JavaScript (V8), 101 byte

f=a=>for(var c=0,i=0;i<a.length;i++,c++)a[i-1]==a[i]?c+=2:a[i-2]==a[i]&&(c++,a[i-1]=void 0)
return c}

Provalo online!

Il codice decompresso si presenta come segue:

function f(a)
{
    var c = 0;
    for (var i = 0; i < a.length; i++, c++)
    {
        if (a[i - 1] == a[i])
            c+=2;
        else if (a[i - 2] == a[i])
            c++,a[i-1]=undefined;
    }

    return c;
}

Il mio primo tentativo di code-golf, probabilmente, può essere ottimizzato molto restringendo l'array e facendolo passare ricorsivamente.


Benvenuti in PPCG! Questo è un ottimo primo post!
Rɪᴋᴇʀ

0

Zsh , 66 60 byte

-6 byte da implicito "$@"

for j
{((i=$a[(I)$j]))&&a=
a=("$a[-1]" $j)
((x+=i+1))}
<<<$x

Provalo online! Consiglio vivamente di aggiungere set -xall'inizio in modo da poter seguire.

for j                   # Implicit "$@"
{                       # Use '{' '}' instead of 'do' 'done'
    (( i=$a[(I)$j] )) \ # (see below)
        && a=           # if the previous returned true, empty a
    a=( "$a[-1]" $j )   # set the array to its last element and the new job
    (( x += i + 1 ))    # add number of slots we advanced
}
<<<$x                   # echo back our total
((i=$a[(I)$j]))
    $a[     ]           # Array lookup
       (I)$j            # Get highest index matched by $j, or 0 if not found
  i=                    # Set to i
((           ))         # If i was set nonzero, return true

acontiene sempre gli ultimi due lavori, quindi se la ricerca trova un lavoro corrispondente in a[2], incrementiamo di tre (poiché gli spazi lavoro saranno[... 3 _ _ 3 ...] ).

Se a non è impostato, la ricerca fallirà e l'espansione aritmetica restituirà un errore, ma ciò accade solo sul primo lavoro e non è fatale.

Se $[x+=i+1]invece utilizziamo invece, possiamo salvare un altro byte e sul sistema degli utenti non sono presenti comandi composti interamente da cifre.


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.