Otomatik BATCH golfçü


25

Tamsayı olmayan destek olmamasına rağmen, şok edici işlevsel komutlar olmamasına rağmen BATCH'ı seviyorum. Niye ya? Çünkü bu işe yarıyor:

SET var=SET
%var% i=0

Bu değerlendirir:

SET var=SET
SET i=0

Harika, değil mi? Bu tekniği daha önce bir BATCH programında kullandım , çünkü bayt kazandırıyor!

Zorluk, kabul ederseniz, BATCH programlarını bu şekilde "golf" yapmak olacaktır. Programın SETbölümlerini değerlendirecek ifadeleri dahil ederek ve başka hiçbir şekilde programı değiştirmeyen ifadeleri dahil ederek bir giriş BATCH programının bayt boyutunu küçülteceksiniz . (Bu, bir değişken adını daha kısa bir şeye yeniden adlandırmayı reddeder. Değişkenlerin dışında BATCH'nin büyük / küçük harfe duyarsız olduğunu unutmayın.) Puanınız şöyle hesaplanır:

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

Programı, test senaryoları için optimize etmek için çalışmayı caydırmak amacıyla daha fazla test vakası ekleme hakkını saklı tutarım.

Bu meydan okuma aşkına, SETtablolar kontrol karakterleri (içeremez |, <, >, %) ya da linebreaks. Bir set ifadesinin içindeki kod parçalarını taşımaktan başka bir kodu değiştiremezsiniz. (Kendisine, değiştirmek, gereksiz boşluk kaldırmayabilir EQUile ==Biz hatları ile sona varsayar, vs.) \n.

Test durumları

Her test durumu ayrı bir kod bloğundadır ve her test durumu kendi içindedir; yani yalnızca içinde ne verildiğini varsayarak golf oynamanız gerektiği anlamına gelir. (Yani, eğer SET d=SETbir programdaysanız, bu ifade otomatik olarak başka bir programa verilmeyecektir). Her örnek sonucu her test durumundan sonra bulabilirsiniz. Test durumları arasında bir çizgi var.

@EKO KAPALI
SET artışı = 10
: döngü
EĞER% artış% EQU 0 GOTO
% ECHO% artış
SET / A% artış% - = 1
GOTO döngüsü
:son
ÇIKIŞ

@EKO KAPALI
SET / p INPUT = Buraya girişi girin:
SET R =% 1
ECHO Buraya girişin son karakteri:% R: ~ -1%

@EKO KAPALI
SET artışı = 10
: e
GOTO f
ECHO f
: f
GOTO g
Eko g
.g
GOTO h
ECHO h
: h
GOTO
EKO ben
:ben
GOTO j
ECHO j
: j
EĞER 3 == 4 (ECHO 4) ELSE (ECHO 5)
5 ise == 3 (GOTO l) ELSE (GOTO k)
: k
ECHO Yapıldı.
ECHO BATCH OUT!
ÇIKIŞ
: l
GOTO g

ECHO Merhaba, Merhaba, Merhaba, merhaba, merhaba, Merhaba, Merhaba !, merhaba, ello !, Lello.

Örnek çıktılar:

@EKO KAPALI
SET artışı = 10
: döngü
EĞER% artış% EQU 0 GOTO
% ECHO% artış
SET / A% artış% - = 1
GOTO döngüsü
:son
ÇIKIŞ
(0 bayt kaydedildi)

@EKO KAPALI
SET% i% = buraya giriş:
SET / p INPUT =% i% yaz
SET R =% 1
ECHO% i% char'in karakter sayısı R: ~ -1%
(3 bayt kazanıldı)

@EKO KAPALI
SET artışı = 10
SET g = GOTO 
SET e = ECHO 
: e
% G% f
% E% f
: f
% G% g
%Örneğin
.g
% G% h
% E% h
: h
% G% ı
% E% ı
:ben
% Gr,% j
% E% j
: j
EĞER 3 == 4 (% e% 4) ELSE (% e% 5)
EĞER 5 == 3 (% g% l) ELSE (% g% k)
: k
% E% yapılan.
% e% BATCH OUT!
ÇIKIŞ
: l
% G% g
(10 karakter kaydedildi)

SET% h% = ello,
ECHO H% h% H% h% H% h% h% h% h% h% h% H% h% Merhaba !, h% h% ello !, Lello.
(1 karakter kaydedildi)


2
Eğlence ve kar için partiyi kısaltın!
Alex Carlsen

Daha fazla spesifikasyona ihtiyacınız var. Elbette AAA %increment%set a=increment¶AAA %%a%%geçersiz ve AAA %1 BBB %2set a= BBB ¶AAA %1%a%%2geçerli. (iirc) Yani resmileştirmelisin. ( yeni bir satırı temsil eder)
user202729

Gecikmeli genişlemeyi etkin kılan, yüzde işareti kaçan ya da / if ifadeleri için çok satırlı kodu kullanmamız gerekir mi? Son test senaryosuna göre (eko açıkken ve daha @önce olmadığı için ek çıktı üretir SET) olduğu gibi, golf programından çıkarılan harici çıktı?
Οurous

1
Tekrar tekrar Tcl
Ven

1
nedeniyle rağmen ?
Adám

Yanıtlar:


4

Java 8, Java 10 , 3884 799/795 programı + 484 çıktı = 4368 1283/1279

Bu kodun iki sınırlaması vardır:

  • A'dan Z'ye değişkenlerin serbest olduğunu varsayar. (Büyük harf)
  • 27'den fazla ikame olmadığı varsayılmaktadır.
  • Oh, ve Tarayıcı çok fazla kesmediğinden boş girdi yığın izini bırakıyor.

Ama hey - bir profesyonel var!

  • En iyi kodu verir. Her zaman.

Kod, meydan yazarı tarafından sağlanan örneklerden daha iyi performans göstermeyi başarıyor.

Bu golf versiyonu Kevin tarafından yapıldı .

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;}

Çevrimiçi deneyin!

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;}

Çevrimiçi deneyin! .

Orijinal versiyon

Hiç golf değil, acı çekmek değil sadece biraz eğlenmek istedim. Siz, sevgili okuyucu, bu cevabı oynamak istiyorsanız, lütfen yapın.

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);
		
		
	}

}

Örnek çıktı:

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

Çevrimiçi deneyin!


Tüm bu "java.util" düşünüyorum. tekrarlayan Kodunuzu basitleştirmek isteyebilirsiniz import java.util.*.
Bir

Jdk ithalatının sayılmadığını düşündüm?
Mark Jeronimus

@A_ cevabımı istediğin gibi değiştirebilirsin (eğer geçerli değilse ve ruhunu koruyamazsa)
Krzysztof Szewczyk

1
" Eğer, sevgili okuyucu, golf Bu cevap istiyorsanız,. Bunu lütfen " 799 bayt Java 8'de veya 795 bayt Java 10+ içinde . Rica ederim. :) Kesinlikle biraz daha golf oynayabiliyorum, ama bu şimdilik.
Kevin Cruijssen

2
@KevinCruijssen Katkı için teşekkürler. Sürümünüzü yayına ekledim. Daha iyi bir şey bulup bulmadığınızı sormadan düzenlemekten çekinmeyin.
Krzysztof Szewczyk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.