Condense esses números de página!

35

Isenção de responsabilidade: enquanto eu estiver neste site para fins de entretenimento há algum tempo, esta é minha primeira pergunta.

fundo

Ao nos atribuir a lição de casa, meu professor é realmente irritante e escreve todos os problemas que temos que fazer individualmente. Como tal, levo uma eternidade para copiar quais problemas eu tenho que fazer. Eu pensei que, para facilitar minha vida, enviaria a ele um programa que poderia fazer com que a lista de problemas ocupasse menos espaço.

Ao escrever uma lista de números de páginas ou problemas, usamos um traço para indicar um intervalo. Por exemplo, 19-21torna-se 19, 20, 21. Se houver um intervalo entre eles, dois intervalos separados por vírgula são usados: 19-21, 27-31torna - se 19, 20, 21, 27, 28, 29, 30, 31.
Agora, você provavelmente está pensando: "isso parece bastante trivial". De fato, isso já foi respondido aqui e aqui .

No entanto, há um porém. Se tivermos um intervalo com dígitos consecutivos iguais, os dígitos repetidos podem ser deixados de fora. Por exemplo: 15, 16, 17torna - se 15-7e 107, 108, 109torna - se 107-9. Para um bônus, se o último dígito igual consecutivo for 1 maior e o último dígito do limite superior for menor ou igual ao inferior, o seguinte poderá ser omitido (desculpe se isso soou confuso; talvez alguns exemplos o esclareçam) . 109-113torna-se109-3 , como um último dígito mais baixo implica aumentar o lugar dos 10s.

Desafio

Seu programa deve receber uma lista de números inteiros via entrada (qualquer que seja o padrão para o seu idioma ou função). Você pode decidir se essa lista é separada por vírgulas, separada por espaço ou como uma lista / matriz real.

Saída da maneira mais curta (primeiro classificada por número de intervalos, depois a soma dos caracteres incluídos nos intervalos) para representar essa lista usando essa notação. Cada intervalo tracejado deve estar na mesma linha, mas os intervalos podem ser separados por vírgulas ou novas linhas (novas linhas ou vírgulas à direita são permitidas). Esses intervalos devem estar em ordem.

Como o Wi-Fi da nossa escola é terrível , tenho que tornar o arquivo o menor possível para enviá-lo a ele. O código mais curto (em bytes) vence.

Bónus

Meu professor é desleixado, então existem algumas coisas que o ajudariam. Vários bônus são acumulados através da multiplicação, por exemplo, um bônus de -10% (x 90%) e um bônus de -25% (x 75%) = 90% * 75% = x 67,5% (bônus de -32,5%).

  • Às vezes, ele os coloca na ordem errada (ele não é um professor de matemática). Receba um bônus de -20% se o seu programa puder aceitar números inteiros que não são classificados da menor para a maior.
  • Nosso livro é estranho e cada seção começa a contar os problemas em -10. Se o seu programa puder aceitar números negativos, pegue -25%.
  • Se ele aceitar o bônus de um último dígito mais baixo, aumentando o lugar dos 10, por exemplo, 25-32reduzindo para 25-2, receba um bônus de -50%.

Casos de teste

In:  1, 2, 3, 4, 5
Out: 1-5

In:  3, 4, 5, 9, 10, 11, 12
Out: 3-5, 9-12

In:  149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160
Out: 149-60

In: 1 2 3 4
Out: 1-4


For bonuses:

In: 109, 110, 111, 112, 113
Out: 109-3

In:  19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
Out: 19-9

In: -3, -2, -1, 0, 1, 2
Out: -3-2

In: -3, -2, -1
Out: -3--1

Uma resposta será aceita no sábado, 19 de dezembro de 2015.

GLHF!

Cyoce
fonte
Por que a saída no terceiro caso de teste não é 1-4 9-2?
Alex A.
Qual deve ser o resultado de um programa que (a) recebe (b) não recebe o bônus de 50% 149 150 151 152 153 154 155 156 157 178 159 160?
lirtosiast
3
Eu podia jurar que há uma outra pergunta como esta, mas eu não posso encontrá-lo ...
mbomb007
5
Eu acho que essa é a questão relacionada com a qual todos estão pensando. Aquele se transforma intervalos em listas embora.
Dennis
11
Outra coisa - o texto diz que o penúltimo dígito para a página final do intervalo deve ser cortado se for menor que o da página inicial, mas o caso de teste indica 19-9para 19,20,...,29e não 19-29como o texto implica. Então, o que está correto?
Zocky

Respostas:

5

LabVIEW, 97 * 0,8 * 0,75 * 0,5 = 29,1 Primitivas do LabVIEW

isso funciona contando para cima se os elemts sucessivos estiverem separados por 1 e, em seguida, criar uma string a partir do módulo número e número - count 10 e alguma multiplicação, pois os negativos são uma cadela.

O gif mostra uma entrada 8,9,10,11e uma saída 8-1. Para entrada -5,-4,-3,1,3,4,5 -5--3,1,3-5sai.

Eumel
fonte
11
Realmente, contando-a como cada loop for / while / if / o que é um primitivo não é justo, porque em linguagens como JS, eles contam como mais de 1 byte ...
ev3commander
@ ev3commander tudo é justo se vier com um diagrama animado legal!
Cyoce 16/12/15
é por isso que está em primitivos, não bytes. Também há muita fiação acontecendo, portanto os loops são de 2 ou 3 pelo menos e também outros 3 por registro de turno + inicialização.
Eumel
11
por regras de golfe padrão que você pode fazer isso, é apenas chato
Eumel
2
@ ev3commander Na verdade, se o idioma for mais recente que o desafio, você não poderá usá-lo por razões competitivas.
Adnan
14

C ++ 11, 451 * 80% * 75% * 50% = 135,3 bytes

Guardado 9 bytes graças a @ kirbyfan64sos.

Economizou 19 bytes graças a @JosephMalle e @cat.

Economizou 11 bytes graças a @ pinkfloydx33.

#include<vector>
#include<cmath>
#include<algorithm>
#include<string>
#define T string
#define P append
using namespace std;T f(vector<int>v){sort(v.begin(),v.end());T r=to_T(v[0]);int b=1;int m=v[0];for(int i=1;i<=v.size();i++){if(i!=v.size()&&v[i]==v[i-1]+1){if(!b){m=v[i-1];}b=1;}else{if(b){T s=to_T(v[i-1]);r.P("-").P(s.substr(s.size()-(v[i-1]-m==1?1:log10(v[i-1]-m)),s.size()));}if(i!=v.size()){r.P(", ").P(to_T(v[i]));}b=0;}}return r;}

Isso se qualifica para todos os bônus.

Exemplo de teste e resultado da amostra:

In:  [1, 2, 3, 4, 5]
Out: 1-5

In:  [3, 4, 5, 9, 10, 11, 12]
Out: 3-5, 9-12

In:  [149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160]
Out: 149-60

In:  [1, 2, 3, 4]
Out: 1-4

In:  [109, 110, 111, 112, 113]
Out: 109-3

In:  [19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
Out: 19-9
TheCoffeeCup
fonte
Por que não usar em intvez de unsigned int? Salva 9 bytes.
Kirbyfan64sos
@ kirbyfan64sos Obrigado, não percebeu isso.
TheCoffeeCup
+1 sempre gosta de ver C ++. Não posso testar isso, mas acho que você não precisa do iostream
sudo rm -rf slash
Eu também não acho que você precise do iostream, mas gccdeu:a.cpp: In function ‘std::string f(std::vector<int>)’: a.cpp:8:83: error: ‘to_string’ was not declared in this scope
cat
@cat Verifique se está atualizado o suficiente para suportar o padrão C ++ 11. 4.3-ish deve ser bom com -std=c++11; > = 5.0 tem por padrão (na verdade é -std=gnu11, mas perto o suficiente).
Mego
8

Ruby, 120 118 * 0,8 * 0,75 * 0,5 = 35,4 bytes

Recebe argumentos da linha de comando como entrada (vírgulas são válidas); imprime um intervalo por linha na saída padrão.

c=(b=(a=$*.map(&:to_i).sort).map &:succ)-a
puts (a-b).map{|m|(m<n=c.shift-1)?"#{m}-#{m<0?n:n%10**"#{n-m-1}".size}":m}

Com espaço em branco / comentários:

c=(
  b=(
    # a is the sorted input
    a=$*.map(&:to_i).sort
  # b is the set of successors of elements of a
  ).map &:succ
# c=b-a is the set of not-quite-least upper bounds of our ranges
)-a

# a-b is the set of greatest lower bounds of our ranges
puts (a-b).map {|m|
  # for each range [m,n], if there are multiple elements
  (m < n = c.shift-1) ?
    # yield the range, abbreviating n appropriately if positive
    "#{m}-#{m<0 ? n : n % 10 ** "#{n-m-1}".size}" :
    # in the one-element case, just yield that
    m
}

Casos de teste

$ ruby homework.rb 1, 2, 3, 4, 5
1-5

$ ruby homework.rb 3, 4, 5, 9, 10, 11, 12
3-5
9-2

$ ruby homework.rb 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160
149-60

$ ruby homework.rb 1 2 3 4
1-4

$ ruby homework.rb 109, 110, 111, 112, 113
109-3

$ ruby homework.rb 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
19-9

Recursos não cobertos por casos de teste

Entradas não ordenadas e intervalos de elemento único:

$ ruby homework.rb 2 17 19 22 0 1 8 20 18
0-2
8
17-0
22

Intervalos negativos (não é possível abreviar o número maior com estes):

$ ruby homework.rb -17 -18 -19 -20 -21
-21--17

Abreviação de números arbitrários de dígitos (expansão bash comum usada para a entrada aqui):

$ ruby homework.rb {1234567..1235467} 2345999 2346000 2346001
1234567-467
2345999-1
ezrast
fonte
Eu acredito que você pode substituir ((n=c.shift-1)>m)porm<n=c.shift-1
Cyoce 21/10
5

Javascript ES6, 229 * 80% * 75% * 50% = 68,7 bytes

Entrada de teste

Estou usando os seguintes dados de teste:

var A1=[
  5,6,7,            // => 5-7     # (a) group pages 
  2,3,              // => 2-3,5-7 # (b) must be properly sorted
  -9,-8,-7,         // => -10--8  # (c) allow negative numbers
  29,30,31,32,      // => 29-2    # (d) lower last digit implies increasing the 10s place
  9,10,11,12,       // => 9-11    # NOT 9-2
  36,37,38,39,40,41,42,43,44,45,46,47, 
                    // => 36-47   # NOT 36-7
  99,100,101,102,   // => 99-102  # NOT 99-2
  109,110,111,112,  // => 109-2   # NOT 109-12
],
// more tests, not specified in the question
A2=[
  120,124,       // => 120,124 # (e) handle single pages
],
A3=[
  135,136,135    // => 135-6   # (f) handle duplicates
];

Básico: 229 bytes

Esta versão atende aos requisitos da pergunta (a) com todos os bônus (c, d, e), mas fica em uma única página. Ele também pode manipular duplicatas (f). Ele lida com páginas negativas de até -10.000, o que pode ser facilmente aumentado com (grande) perda de velocidade.

F=(a)=>{var R=[],i=NaN,l,u;a.map(x=>R[1e4+x]=x);R.concat('').map(x=>(i!=i&&(l=x,u=l-1),i=0,u=(x+="")-u-1?l=console.log(l+'-'+(u>0?(l.length-u.length||(z=>{for(;l[i]==u[i];i++);})(),u.length-i-2||u-l>9||i++,u.slice(i)):u))||x:x))}
F(A1.concat(A3)) --> -9--7 2-3 5-7 9-12 29-2 36-47 99-102 109-2 135-136

(A saída acima mostra espaços em vez de novas linhas reais, por questões de concisão)

Páginas únicas: 233 bytes

Essa versão um pouco mais longa também satisfaz (e) e exibe páginas únicas como um intervalo com limites inferior e superior iguais

G=(a)=>{var R=[],i=NaN,l,u;a.map(x=>R[1e4+x]=x);R.concat('').map(x=>(i!=i&&(l=x,u=l-1),i=0,u=(x+="")-u-1?l=console.log(l+'-'+(u-l&u>0?(l.length-u.length||(z=>{for(;l[i]==u[i];i++);})(),u.length-i-2||u-l>9||i++,u.slice(i)):u))||x:x))}
G(A1.concat(A2,A3)) --> -9--7 2-3 5-7 9-12 29-2 36-47 99-102 109-2 120-120 124-124
zocky
fonte
@Cyoce - Você está usando um mecanismo javascript habilitado para ES6?
Zocky
Ah, hmm, eu tenho um bug, ele não lida com 36-47 corretamente. Qual é o procedimento adequado? Eu o apago e corrigo, ou apenas tento corrigi-lo (talvez eu não tenha tempo agora), ou o quê?
Zocky
Hmm, ele simplesmente funciona no meu Chrome. O que da?
Zocky
E zocky, conserte-o quando puder. Apenas não será considerado válido até que seja corrigido e, como tal, não poderá ser aceito até então (supondo que o seu seja o menor número de bytes).
Cyoce
3

GAP , 355 bytes * 0,8 * 0,75 * 0,5 = 106,5

Isso satisfaz todos os bônus. Custou-me quase 100 bytes extras para fazer tudo funcionar bem. Esta função omite apenas os dígitos iniciais se o espaço não exceder o número colocado uma vez. Por exemplo9 10 11 saídas, 9-1mas 9 10 11 12 .. 20 21saídas9-21 .

Se o GAP fosse um pouco menos detalhado, eu poderia ter ficado tão curto (também poderia ter economizado muitos bytes se não seguisse a sintaxe exata). Provavelmente tentarei jogar um pouco mais difícil amanhã. Veja abaixo os casos de teste.

g:=function(l)local n;if not l=[] then Sort(l);n:=1;while not l=[] do;if not IsSubset(l,[l[1]..l[1]+n]) then if not n=1 then if n-1>10-l[1] mod 10 and n-1<11 then Print(l[1],"-",(l[1]+n-1) mod 10);else Print(l[1],"-",l[1]+n-1);fi;else Print(l[1]);fi;Print(", ");SubtractSet(l,[l[1]..l[1]+n-1]);g(l);fi;n:=n+1;od;fi;Print("\b\b  ");end; 

ungolfed:

g:=function(l)
    local n;
    if not l=[] then
        Sort(l);
        n:=1;
        while not l=[] do;
            if not IsSubset(l,[l[1]..l[1]+n]) then
                if not n=1 then
                    if n-1>10-l[1] mod 10 and n-1<11 then
                        Print(l[1],"-",(l[1]+n-1) mod 10);
                    else
                        Print(l[1],"-",l[1]+n-1);
                    fi;
                else
                    Print(l[1]);
                fi;
                Print(", ");
                SubtractSet(l,[l[1]..l[1]+n-1]);
                g(l);
            fi;
            n:=n+1;
        od; 
    fi;
    Print("\b\b  ");
end;

Observe que na sintaxe GAP, [a..b]é equivalente a [a,a+1,...,b]. Acredito que esses casos de teste demonstrem que este programa atende a todos os requisitos. Se algo estiver errado, me avise.

gap> h([1..5]);
1-5  
gap> h([3,4,5,9,10,11,12]);
3-5, 9-2  
gap> h([149..160]);
149-160  
gap> h([109..113]);
109-3  
gap> h([19..29]);
19-9  

gap> h([-1,-2,-3,-7,-20000,9,10,110101,110102]);
-20000, -7, -3--1, 9-10, 110101-110102  

gap> h([10101,10102,10103,10,11,12,13,14,15,16,234,999,1000,1001,1002]);
10-16, 234, 999-2, 10101-10103  
Liam
fonte
3

Lua, 322 * 80% * 75% * 50% = 96,6 bytes

Finalmente concluído com os 3 desafios, Pontuações abaixo de 100 bytes: D

Golfe

function f(l)table.sort(l)l[#l+1]=-13 a=l[1]t,s=a,"" for _,v in next,l do if v-t>1 or t-v>1 then s,p,r=s..a.."-",""..t,""..a r:gsub("%d",function(c)p=r:find(c)~=r:len()and p:gsub("^(-?)"..c,"%1")or p r=r:gsub("^"..c,"")end)p=t-a<10 and t%10<a%10 and p:gsub("^(%d)","")or p s,a,t=s..p..",",v,v else t=v end end return s end

Ungolfed

function f(l)
    table.sort(l)
    l[#l+1]=-13 
    a=l[1] 
    t,s=a,"" 
    for _,v in next,l 
    do
        if v-t>1 or t-v>1
        then
            s,p,r=s..a.."-",""..t,""..a
            r:gsub("%d",function(c)
                p=r:find(c)~=#r and p:gsub("^(-?)"..c,"%1")or p
                r=r:gsub("^"..c,"")
            end)
            p=t-a<10 and t%10<a%10 and p:gsub("^(%d)","")or p
            s=s..p..","
            a,t=v,v
        else
            t=v
        end
    end
return s
end

Você pode testar o lua online , para ver como ele se comporta nos casos de teste, copiar e colar a função, seguida por este código:

a={1,2,3,4,5}
b={3,4,5,9,10,11,12,13,14,15,16,17,18,19,20,21}
c={149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160}
d={-7,8,5,-6,-5,6,7}
print(f(a))
print(f(b))
print(f(c))
print(f(d))
Katenkyo
fonte
Parece falhar se {9..21} for inserido. Saídas 9-1.
Liam
@ICanHazHats fixo, obrigado por apontar isso :)
Katenkyo
2

Java, 252 * 80% * 75% * 50% = 75,6 bytes

Eu decidi ir para um método (é muito menor em Java), aqui está a versão golfed:

Golfe

int p,c,s;String m(int[]a){p=s=c=0;c--;String o="";Arrays.sort(a);for(int n:a){if(s==0)o+=s=n;else if(n-p==1)c++;else{o+=t()+", "+(s=n);c=-1;}p=n;}return o+t();}String t(){return c>=0?"-"+(""+p).substring((""+Math.abs(p)).length()-(""+c).length()):"";}

E aqui está a versão legível:

int p, c, s;

String m(int[] a) {
    p = s = c = 0;
    c--;
    String o = "";
    Arrays.sort(a);
    for (int n : a) {
        if (s == 0)
            o += s = n;
        else if (n - p == 1)
            c++;
        else {
            o += t() + ", " + (s = n);
            c = -1;
        }
        p = n;
    }
    return o + t();
}

String t() {
    return c >= 0 ? "-" + ("" + p).substring(("" + Math.abs(p)).length() - ("" + c).length()) : "";
}

Quando testados, estes são os resultados:

import java.util.Arrays;
public class A {
    public static void main(String...s) {
        A a = new A();
        System.out.println(a.m(new int[] {1, 2, 3, 4, 5}));
        System.out.println(a.m(new int[] {3, 4, 5, 9, 10, 11, 12}));
        System.out.println(a.m(new int[] {149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160}));
        System.out.println(a.m(new int[] {109, 110, 111, 112, 113}));
        System.out.println(a.m(new int[] {19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}));
        System.out.println(a.m(new int[] {1,10,11,16}));
        System.out.println(a.m(new int[] {-3,-2,-1,0,1,2,3}));
        System.out.println(a.m(new int[] {-3,-2,-1}));
    }

    int p,c,s;String m(int[]a){p=s=c=0;c--;String o="";Arrays.sort(a);for(int n:a){if(s==0)o+=s=n;else if(n-p==1)c++;else{o+=t()+", "+(s=n);c=-1;}p=n;}return o+t();}String t(){return c>=0?"-"+(""+p).substring((""+Math.abs(p)).length()-(""+c).length()):"";}
}

Saída:

1-5
3-5, 9-2
149-60
109-3
19-9
1, 10-1, 16
-3-3
-3--1

Atualizar:

Agora ele também pode lidar com números negativos, aumentando o bônus.

Roy van Rijn
fonte
Não sou especialista em Java, mas você pode reduzi-lo mudando p=s=c=0;c--;para p=s=0;c=-1;?
Cyoce 16/12/2015
Não sou especialista em Java, mas você pode reduzi-lo alterando return c> = 0? "bla": "" para retornar c <0? "": "bla"?
Stephan Schinkel
você pode até fazer c=~(p=s=0)pontos de estilo.
Cyoce 18/12/2015
2

Japt, 127 bytes * 80% * 75% * 50% = 38,1

Uau, esse foi um desafio enorme para incluir todos os bônus. Provavelmente poderia ser reduzido.

D=[]N=Nn-;DpNr@Y-1¥Xg1 ?[Xg Y]:DpX ©[YY]}D;Ds1 £[BC]=Xms;B¥C?B:B+'-+CsBg ¦'-©Cl ¥Bl ©C¬r@B¯Z ¥C¯Z ªC-B§ApCl -Z ©ÂBsX <ÂCsX ?Z:X

Experimente online!

Como funciona

A explicação é muito grosseira; não hesite em fazer qualquer pergunta que possa ter.

/*    Setting up basic variables    */
                      // Implicit: A = 10, N = list of input numbers.
D=[],N=Nn-;           // D = empty array, N = N sorted by subtraction.

/*    Finding ranges of page numbers    */    
Dp                    // Push into D the result of
NrXYZ{                // reducing each previous value X and item Y in N by this function,
}[];                  // starting with an empty array:
 Y-1==Xg1 ?           //  If Y is 1 more than the second item of X,
 [Xg Y]:              //   return [X[0], Y].
 DpX &&[YY]           //  Otherwise, push X into D and return [Y, Y].

/*    Formatting result    */
Ds1 mXYZ{             // Take the first item off of D and map each item X by this function:
 [BC]=Xms;            //  Set B and C to the first to items in X as strings.
 B==C?B               //  If B is the same as C, return B.
 :B+'-+Cs             //  Otherwise, return B + a hyphen + C.slice(
  Bg !='-&&           //   If B[0] is not a hyphen (B is not negative), AND
  Cl ==Bl &&          //   B and C are the same length,

  /*    Cutting off unnecessary digits    */
  Cq r                //    then C split into digits, reduced with
  rXYZ{               //    each previous value X, item Y, and index Z mapped by this function:
   Bs0,Z ==Cs0,Z ||   //     If B.slice(0,Z) equals C.slice(0,Z), OR
   C-B<=ApCl -Z       //     C - B <= 10 to the power of (C.length - Z);
   &&~~BsX <~~CsX     //     AND B.slice(X) is a smaller number than C.slice(X),
   ?Z:X               //     then Z; otherwise, X.
                      //   Otherwise, 0.
ETHproductions
fonte
1

R, 167 bytes x 80% x 75% x 50% -> 50,1

s=sort(scan(se=","));r=c();while(length(s)){w=s==1:length(s)+s[1]-1;x=s[w];s=s[!w];z=tail(x,1);r=c(r,paste0(x[1],"-",ifelse(z-x[1]<=10,z%%10,z%%100)))};cat(r,sep=", ")

Recuado, com novas linhas:

s=sort(scan(se=","))
r=c()
while(length(s)){
w=s==1:length(s)+s[1]-1
x=s[w]
s=s[!w]
z=tail(x,1)
r=c(r, paste0(x[1],"-", ifelse(z-x[1]<=10, 
                               z%%10,
                               z%%100)))}
cat(r,sep=", ")

Casos de teste:

> s=sort(scan(se=","));r=c();while(length(s)){w=s==1:length(s)+s[1]-1;x=s[w];s=s[!w];r=c(r,paste0(x[1],"-",ifelse(tail(x,1)-x[1]<=10,tail(x,1)%%10,tail(x,1)%%100)))};cat(r,sep=", ")
1: 3, 4, 5, 9, 10, 11, 12
8: 
Read 7 items
3-5, 9-2
> s=sort(scan(se=","));r=c();while(length(s)){w=s==1:length(s)+s[1]-1;x=s[w];s=s[!w];r=c(r,paste0(x[1],"-",ifelse(tail(x,1)-x[1]<=10,tail(x,1)%%10,tail(x,1)%%100)))};cat(r,sep=", ")
1: 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160
13: 
Read 12 items
149-60

Funciona com o bônus de -50%:

> s=sort(scan(se=","));r=c();while(length(s)){w=s==1:length(s)+s[1]-1;x=s[w];s=s[!w];r=c(r,paste0(x[1],"-",ifelse(tail(x,1)-x[1]<=10,tail(x,1)%%10,tail(x,1)%%100)))};cat(r,sep=", ")
1: 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
12: 
Read 11 items
19-9
> s=sort(scan(se=","));r=c();while(length(s)){w=s==1:length(s)+s[1]-1;x=s[w];s=s[!w];r=c(r,paste0(x[1],"-",ifelse(tail(x,1)-x[1]<=10,tail(x,1)%%10,tail(x,1)%%100)))};cat(r,sep=", ")
1: 109, 110, 111, 112, 113
6: 
Read 5 items
109-3

Aceita entrada não classificada:

> s=sort(scan(se=","));r=c();while(length(s)){w=s==1:length(s)+s[1]-1;x=s[w];s=s[!w];r=c(r,paste0(x[1],"-",ifelse(tail(x,1)-x[1]<=10,tail(x,1)%%10,tail(x,1)%%100)))};cat(r,sep=", ")
1: 114, 109, 110, 111, 112, 113
7: 
Read 6 items
109-4

Aceita números negativos:

> s=sort(scan(se=","));r=c();while(length(s)){w=s==1:length(s)+s[1]-1;x=s[w];s=s[!w];r=c(r,paste0(x[1],"-",ifelse(tail(x,1)-x[1]<=10,tail(x,1)%%10,tail(x,1)%%100)))};cat(r,sep=", ")
1: -1,0,1,2
4: 
Read 3 items
-1-2
plannapus
fonte
0

sh, 135 * .8 * .75 * .5 = 40,5

tr , \\n|sort -n|awk -vORS="" '$1-o>1||!c{print p c$1;s=$1}{o=$1;c=", ";p=""}o>s{p="-"substr(o,length(o)-length(o-s-1)+1)}END{print p}'

script de shell

tr , \\n|           # comma separated -> newline separated
sort -n|            # sort
awk -vORS=""        # suppress automatic newlines in output

script awk

# on step > 1 or first run, end the current sequence and start a new one.
# on first run, p and c are empty strings.
$1-o>1||!c
    {print p c$1;s=$1}

# old = current, c = ", " except for first run, clear end string.
    {o=$1;c=", ";p=""}

# if the sequence is not a single number, its end is denoted by "-o".
# print only the last n digits of o.
o>s
    {p="-"substr(o,length(o)-length(o-s-1)+1)}

# end the current sequence without starting a new one.
END
    {print p}'

onde sé o início da sequência atual e oé o valor de entrada anterior.

Rainer P.
fonte
Gosto, mas atualmente não recebe o bônus de -25%. substr () está cortando sinais de menos e dígitos significativos.
ezrast
@ezrast Na verdade, esse é um comportamento correto em termos de bônus de -50%: -31, -30, -29, -28aumentos no lugar dos 10s de -3para -2e, portanto, devem ser condensados ​​em -31-8. Eu também vejo a ambiguidade que ela cria, mas é isso que é solicitado.
Rainer P.