Jogador de golfe auto


25

Eu amo BATCH, apesar de sua falta chocante de comandos funcionais, apesar de ainda devido à falta de suporte não inteiro. Por quê? Porque isso funciona:

SET var=SET
%var% i=0

Isso avaliaria:

SET var=SET
SET i=0

Fantástico, não é? Eu usei essa técnica em um programa BATCH antes, porque salva bytes!

Seu desafio, se você o aceitar, seria "jogar golfe" nos programas BATCH dessa maneira. Você deve diminuir o tamanho de byte de um programa BATCH de entrada incluindo SETinstruções que seriam avaliadas em partes do programa e de nenhuma outra maneira modificar o programa. (Isso proíbe, por exemplo, renomear um nome de variável para algo mais curto. Lembre-se de que BATCH, além das variáveis, não diferencia maiúsculas de minúsculas.) Sua pontuação é calculada da seguinte forma:

score = # of characters in your program + 5*(net result bytes in test cases below)

Reservo-me o direito de adicionar mais casos de teste, para desencorajar o trabalho de otimizar o programa para os casos de teste.

Por causa deste desafio, suas SETdeclarações não podem conter caracteres de controle ( |, <, >, %) ou quebras de linha. Você não pode modificar o código senão mover partes do código dentro de uma instrução set. (Ou seja, você não pode remover espaços em branco desnecessários, substituir EQUpor ==etc.) Assumiremos que as linhas terminam com \n.

Casos de teste

Cada caso de teste está em um bloco de código separado e cada caso de teste é independente, o que significa que você deve jogar golfe apenas assumindo o que é fornecido dentro dele. (Ou seja, se você estiver SET d=SETem um programa, essa declaração não será dada automaticamente a nenhum outro programa). Cada exemplo de resultado pode ser encontrado após cada caso de teste. Há uma linha entre os casos de teste.

@ECHO OFF
SET incremento = 10
: loop
IF% incremento% EQU 0 GOTO final
ECHO% incremento%
SET / A% incremento% - = 1
Loop GOTO
:fim
SAÍDA

@ECHO OFF
SET / p INPUT = Insira a entrada aqui:
SET R =% 1
ECHO Último caractere de entrada aqui:% R: ~ -1%

@ECHO OFF
SET incremento = 10
: e
GOTO f
ECHO f
: f
GOTO g
ECHO g
: g
GOTO h
ECHO h
: h
GOTO i
ECHO i
:Eu
GOTO j
ECHO j
: j
IF 3 == 4 (ECHO 4) ELSE (ECHO 5)
SE 5 == 3 (GOTO l) MAIS (GOTO k)
: k
ECHO Feito.
ECHO BATCH OUT !!
SAÍDA
:eu
GOTO g

Olá, olá, olá, olá, olá, olá, olá !, olá, ello !, olá.

Exemplo de saídas:

@ECHO OFF
SET incremento = 10
: loop
IF% incremento% EQU 0 GOTO final
ECHO% incremento%
SET / A% incremento% - = 1
Loop GOTO
:fim
SAÍDA
(0 bytes salvos)

@ECHO OFF
SET% i% = entrada aqui:
SET / p INPUT = Digite% i%
SET R =% 1
Último caractere do ECHO de% i %% R: ~ -1%
(3 bytes ganhos)

@ECHO OFF
SET incremento = 10
SET g = GOTO 
SET e = ECHO 
: e
% g% f
% e% f
: f
% g% g
%por exemplo
: g
% g% h
%Eh
: h
% g% i
% e% i
:Eu
% g% j
% e% j
: j
IF 3 == 4 (% e% 4) ELSE (% e% 5)
IF 5 == 3 (% g% l) ELSE (% g% k)
: k
% e% Concluído.
% e% BATCH OUT !!
SAÍDA
:eu
% g% g
(10 caracteres salvos)

SET% h% = ello,
ECHO H% h% H% h% H% h% h% h% h% h% H% h% Olá !, h% h% ello !, Lello.
(1 caractere salvo)


2
Encurtando lote para diversão e lucro!
Alex Carlsen 23/02

Você precisa de mais algumas especificações. Obviamente AAA %increment%set a=increment¶AAA %%a%%é inválido e AAA %1 BBB %2set a= BBB ¶AAA %1%a%%2é válido. (IIRC) Então você precisa formalizá-lo. ( representa uma nova linha)
user202729 23/05

Precisamos lidar com código que atrasou a expansão ativada, escapes de sinal de porcentagem ou instruções multi-line para / if? De acordo com o último caso de teste (que produz saída adicional quando o eco está ativado e não há @antes do SET), a saída estranha é aceitável no programa de golfe?
Οurous

11
Tcl tudo de novo
Ven

11
apesar mesmo devido a ?
Adám 29/08

Respostas:


4

Java 8, Java 10 , 3884Programa 799/795 + saída 484 = 4368 1283/1279 total

Existem duas limitações desse código:

  • Assume que as variáveis ​​de A a Z são livres. (maiúsculas)
  • Pressupõe que não haja mais de 27 substituições.
  • Ah, e como o Scanner não resolve, as entradas vazias eliminam o rastreamento de pilha.

Mas ei - existe um profissional!

  • Produz o melhor código. Sempre.

O código consegue ter um desempenho melhor que os exemplos fornecidos pelo autor do desafio.

Esta versão para golfe foi feita por Kevin .

Java 8

c->{List<String>S=new Stack();HashMap<String,Integer>h=new HashMap(),s=new HashMap();int v=65,l=c.length(),b,e;do{for(b=0,l=c.length(),s.clear();b!=l;b++)for(e=b;++e<=l;)S.add(c.substring(b,e));S.removeIf(t->t.length()<5|t.matches(".*[\n|<%>].*"));S.forEach(t->h.merge(t,1,Integer::sum));S.clear();h.entrySet().removeIf(t->t.getValue()==1);String Y=c;int L=l;char V=(char)v;h.forEach((k,x)->{String i=Y,t;for(int j,I,q;i.contains(k);i=t+"%"+V+"%"+i.substring(j+k.length(),i.length())){for(I=-1,t=i.substring(q=0,j=i.indexOf(k));(I=t.indexOf("%",++I))>=0;q++);if(q%2>0)return;}i="SET "+V+"="+k+"\n"+i;if(i.length()<L)s.put(i,L-i.length());});h.clear();v++;c=s.isEmpty()?c:s.entrySet().stream().max((x,y)->x.getValue()>y.getValue()?1:-1).get().getKey();}while(l>c.length());return c;}

Experimente online!

Java 10

c->{var S=new Stack<String>();HashMap<String,Integer>h=new HashMap(),s=new HashMap();int v=65,l=c.length(),b,e;do{for(b=0,l=c.length(),s.clear();b!=l;b++)for(e=b;++e<=l;)S.add(c.substring(b,e));S.removeIf(t->t.length()<5|t.matches(".*[\n|<%>].*"));S.forEach(t->h.merge(t,1,(x,y)->x+y));S.clear();h.entrySet().removeIf(t->t.getValue()==1);var Y=c;int L=l;var V=(char)v;h.forEach((k,x)->{String i=Y,t;for(int j,I,q;i.contains(k);i=t+"%"+V+"%"+i.substring(j+k.length(),i.length())){for(I=-1,t=i.substring(q=0,j=i.indexOf(k));(I=t.indexOf("%",++I))>=0;q++);if(q%2>0)return;}i="SET "+V+"="+k+"\n"+i;if(i.length()<L)s.put(i,L-i.length());});h.clear();v++;c=s.isEmpty()?c:s.entrySet().stream().max((x,y)->x.getValue()>y.getValue()?1:-1).get().getKey();}while(l>c.length());return c;}

Experimente online!.

Versão original

Não é golfe, eu só queria me divertir um pouco, para não sofrer. Se você, caro leitor, gostaria de jogar esta resposta, faça-o.

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class Main {
	List<String> substrings = new ArrayList<String>();
	HashMap<String, Integer> hm = new HashMap<String, Integer>();
	HashMap<String, Integer> scores = new HashMap<String, Integer>();
	
	private int v1 = 65;
	
	public static String rfos(String inputString, String stringToReplace,
	        String stringToReplaceWith) {

	    int length = stringToReplace.length();
	    int inputLength = inputString.length();

	    int startingIndexofTheStringToReplace = inputString.indexOf(stringToReplace);

	    if(count(inputString.substring(0, startingIndexofTheStringToReplace), "%") % 2 == 1)
	    	return null;
	    
	    String finalString = inputString.substring(0, startingIndexofTheStringToReplace) + stringToReplaceWith
	            + inputString.substring(startingIndexofTheStringToReplace + length, inputLength);

	    return finalString;

	}
	
	public static int count(String text, String find) {
        int index = 0, count = 0, length = find.length();
        while( (index = text.indexOf(find, index)) != -1 ) {                
                index += length; count++;
        }
        return count;
	}
	
	private String process(String program) {
		int begin = 0, end, il = program.length();
		
		scores.clear();
		
		while(begin != program.length()) {
			for(end = begin + 1; end < program.length() + 1; end++)
				substrings.add(program.substring(begin, end));
			begin++;
		}
		
		substrings.removeIf(new Predicate<String>() {
			@Override
			public boolean test(String arg0) {
				return arg0.length() <= 4 || arg0.contains("\n")
						|| arg0.contains("|")
						|| arg0.contains("<")
						|| arg0.contains("%")
						|| arg0.contains(">");
			}
		});
		
		substrings.forEach(new Consumer<String>() {

			@Override
			public void accept(String t) {
				if(hm.containsKey(t)) {
					hm.replace(t, hm.get(t) + 1);
				} else {
					hm.put(t, 1);
				}
			}
			
		});
		
		substrings.clear();
		
		hm.entrySet().removeIf(new Predicate<Map.Entry<String, Integer>>() {

			@Override
			public boolean test(Map.Entry<String, Integer> t) {
				return t.getValue() == 1;
			}
			
		});
		
		hm.forEach(new BiConsumer<String, Integer>() {
			
			@Override
			public void accept(String arg0, Integer arg1) {
				String iteration = program;
				boolean between = false;
				while(iteration.contains(arg0)) {
					iteration = rfos(iteration, arg0, "%" + Character.toString((char) v1) + "%");
					if(iteration == null)
						return;
				}
				iteration = "SET " + Character.toString((char) v1) + "=" + arg0 + "\n" + iteration;
				if(iteration.length() < program.length())
					scores.put(iteration, program.length() - iteration.length());
			}
			
		});
		
		hm.clear();
		v1++;
		
		if(scores.isEmpty())
			return program;
		else
			return scores.entrySet().stream().max((entry1, entry2) -> entry1.getValue() > entry2.getValue() ? 1 : -1).get().getKey();
	}

	public static void main(String[] args) {
		Main processor = new Main();
		int genid = 0, before = 0, after = 0;
		String currentCode = new Scanner(System.in).useDelimiter("\\Z").next();
		
		System.out.println("Calculating first generation...");
		
		do {
			String cc = processor.process(currentCode);
			before = currentCode.length();
			after = cc.length();
			
			currentCode = cc;
			
			if(before > after) {
				System.out.println("Generation " + genid++);
				System.out.println(before + " -> " + after);
				System.out.println("***\n" + cc + "\n***");
			} else {
				System.out.println("Generation FAIL " + genid++);
				System.out.println(before + " -> " + after);
				System.out.println("***\n" + cc + "\n***");
			}
		} while(before > after);
		
		
	}

}

Exemplo de saída:

SET B=GOTO 
SET A=ECHO 
@%A%OFF
SET increment=10
:e
%B%f
%A%f
:f
%B%g
%A%g
:g
%B%h
%A%h
:h
%B%i
%A%i
:i
%B%j
%A%j
:j
IF 3==4 ( %A%4 ) ELSE ( %A%5 )
IF 5==3 ( %B%l ) ELSE ( %B%k )
:k
%A%Done.
%A%BATCH OUT!!
EXIT
:l
%B%g

Experimente online!


Eu acho que tudo isso "java.util". é repetitivo. Você pode querer simplificar seu código para import java.util.*.
A

Eu pensei que as importações jdk não contam?
Mark Jeronimus

@A_ você pode modificar minha resposta como desejar (a menos que seja válida e mantenha o espírito)
Krzysztof Szewczyk

11
" Se você, caro leitor, gostaria de jogar esta resposta, faça-o. " 799 bytes em Java 8 ou 795 bytes em Java 10+ . De nada. :) Definitivamente pode ser jogado um pouco mais, mas isso servirá por enquanto.
Kevin Cruijssen 29/08

2
@KevinCruijssen Obrigado pela contribuição. Adicionei sua versão à postagem. Sinta-se livre para editá-lo sem me perguntar se você encontra algo melhor.
Krzysztof Szewczyk
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.