Java: 1523 1512 karakter
import java.util.*;class W{int v=99;Map<Integer,String>t;boolean k;public static void main(String[]y){new W().d();}W(){try{java.io.InputStream i=new java.io.File("r").toURL().openStream();t=new HashMap<>();int a=0,x=0,y=0;while((a=i.read())>-1){if(a==10){y++;x=0;continue;}q(x,y,(a>47&a<58?"!":"")+(char)a);x++;}}catch(Exception e){}}void d(){while(!k){k=!k;for(Map.Entry<Integer,String>g:t.entrySet())e(g.getKey(),g.getValue());}for(String b:t.values())if(b.startsWith("$"))System.out.println(b.substring(1));}void e(int a,String s){if(s==null||!s.startsWith("!"))return;int x=a/v,y=a%v;s=s.substring(1);b(s,x,y,x-1,y+1);b(s,x,y,x,y+1);b(s,x,y,x+1,y+1);b(s,x,y,x-1,y);b(s,x,y,x+1,y);b(s,x,y,x-1,y-1);b(s,x,y,x,y-1);b(s,x,y,x+1,y-1);}void b(String p,int m,int n,int x,int y){String s=t.get(x*v+y);if(s==null)return;boolean g=y==n+1;boolean h=y==n-1;boolean i=x==m+1;boolean j=x==m-1;if(z(s,"-=")&n==y){if(i)b(p,x,y,x+1,y);if(j)b(p,x,y,x-1,y);}if(z(s,"|=")&m==x){if(g)b(p,x,y,x,y+1);if(h)b(p,x,y,x,y-1);}if(z(s,"/=")){if(j&g)b(p,x,y,x-1,y+1);if(i&h)b(p,x,y,x+1,y-1);}if(z(s,"\\=")){if(i&g)b(p,x,y,x+1,y+1);if(j&h)b(p,x,y,x-1,y-1);}if(z(s,".")){q(x,y,"!"+p);u();}if(z(s,"~")){q(x,y,"!~("+p+")");u();}if((s.charAt(0)=='%'&n==y-1)|(s.charAt(0)=='&'&n==y+1)){q(x,y,"!("+p+")"+s.charAt(1)+"("+s.substring(2)+")");u();}if(z(s,"OoAaXx")){q(x,y,(n==y+1?"%":"&")+s+p);u();}if(z(s,":")){q(x,y,"$"+p);u();}}void q(int x,int y,String z){t.put(x*v+y,z);}void u(){k=false;}boolean z(String s,String c){return c.indexOf(s)>-1;}}
Bu çıktıyı örnek girişi için verir:
(~(((5)X(4))O(3)))a(~(1))
((~(((5)X(4))O(3)))a(~(1)))X(((2)x(1))x(3))
Boyutunu sıkmak için:
- Girişin her zaman geçerli olduğu varsayılarak hata kontrolü, hata işleme veya giriş doğrulaması yapmaz.
- 99 satır giriş ile sınırlıdır.
- Girdi dosyası, adında
r
herhangi bir dosya uzantısı olmadan sadece çağrılmalıdır .
- Parantezin gerekli olup olmadığını tespit etmek için hiçbir çaba sarf etmez. Her zaman gerekli olduklarını varsayar ve bu varsayım yanlış olduğundan, gerekenden çok daha fazla parantez vardır, ancak bu yine de spesifikasyonu başarısız kılmadığı için sorun değildir.
- Her bir ikili operatöre parametrelerin sırası, değerlerin yayılma hızına ve hücre tarama sırasına bağlı olduğundan genel olarak öngörülemez. Ancak tüm ikili operatörler değişmeli olduğu için bu sorun olmamalı.
Eminim daha fazla, ancak biraz azaltmak mümkün olmalıdır.
Yorumlayıcı bir çeşit hücresel otomata şeklinde uygulanır. Tüm alan ayarı değerlerini tarar ve hiçbir değişiklik algılanana kadar gerektiği kadar tekrarlar.
İşte ungolfed versiyonu:
import java.util.*;
class Wiring {
int maxLines = 99;
Map<Integer, String> circuitState;
boolean finished;
public static void main(String[] args) {
new Wiring().interpret();
}
Wiring() {
try {
// Always read the input from the "r" file, and do not check if it even
// exists. BTW, the toURL() method is deprecated, but we don't care about
// this in code-golfing.
java.io.InputStream stream = new java.io.File("r").toURL().openStream();
circuitState = new HashMap<>();
int byteRead = 0, cellX = 0, cellY = 0;
while ((byteRead = stream.read()) > -1) {
// Check for line break;
if (byteRead == 10) {
cellY++;
cellX = 0;
continue;
}
// Populate the circuit cell. Precede numbers with an exclamation mark.
setCircuitCell(cellX, cellY, (byteRead >= '0' & byteRead <= '9' ? "!" : "") + (char) byteRead);
cellX++;
} catch (Exception e) {
}
}
void interpret() {
while (!finished) {
finished = !finished; // i.e. finished = false;
for (Map.Entry<Integer, String> entry : circuitState.entrySet()) {
analyzeCell(entry.getKey(), entry.getValue());
}
}
// Now print the output. To do that scan for cells marked with "$".
for (String cell : circuitState.values()) {
if (cell.startsWith("$")) System.out.println(cell.substring(1));
}
}
void analyzeCell(int cellIndex, String cellValue) {
// Only the cells with a value marked with "!" are worth to analyze.
if (cellValue == null || !cellValue.startsWith("!")) return;
// Convert the cellIndex to a bidimensional coordinate.
int x = cellIndex / maxLines, y = cellIndex % maxLines;
// Remove the "!".
cellValue = cellValue.substring(1);
// Propagate the cell value to neighbouring cells.
propagateCellData(cellValue, x, y, x - 1, y + 1);
propagateCellData(cellValue, x, y, x, y + 1);
propagateCellData(cellValue, x, y, x + 1, y + 1);
propagateCellData(cellValue, x, y, x - 1, y);
propagateCellData(cellValue, x, y, x + 1, y);
propagateCellData(cellValue, x, y, x - 1, y - 1);
propagateCellData(cellValue, x, y, x, y - 1);
propagateCellData(cellValue, x, y, x + 1, y - 1);
}
void propagateCellData(String cellValue, int sourceX, int sourceY, int targetX, int targetY) {
String targetContent = circuitState.get(targetX * maxLines + targetY);
// If the target cell does not exist, just ignore.
if (targetContent == null) return;
boolean targetBelowSource = targetY == sourceY + 1;
boolean targetAboveSource = targetY == sourceY - 1;
boolean targetRightToSource = targetX == sourceX + 1;
boolean targetLeftToSource = targetX == sourceX - 1;
// Propagate horizontally through wires.
if (isStringContained(targetContent, "-=") & sourceY == targetY) {
if (targetRightToSource) propagateCellData(cellValue, targetX, targetY, targetX + 1, targetY);
if (targetLeftToSource) propagateCellData(cellValue, targetX, targetY, targetX - 1, targetY);
}
// Propagate vertically.
if (isStringContained(targetContent, "|=") & sourceX == targetX) {
if (targetBelowSource) propagateCellData(cellValue, targetX, targetY, targetX, targetY + 1);
if (targetAboveSource) propagateCellData(cellValue, targetX, targetY, targetX, targetY - 1);
}
// Propagate in the diagonal x=-y.
if (isStringContained(targetContent, "/=")) {
if (targetLeftToSource & targetBelowSource) {
propagateCellData(cellValue, targetX, targetY, targetX - 1, targetY + 1);
}
if (targetRightToSource & targetAboveSource) {
propagateCellData(cellValue, targetX, targetY, targetX + 1, targetY - 1);
}
}
// Propagate in the diagonal x=y.
if (isStringContained(targetContent, "\\=")) {
if (targetRightToSource & targetBelowSource) {
propagateCellData(cellValue, targetX, targetY, targetX + 1, targetY + 1);
}
if (targetLeftToSource & targetAboveSource) {
propagateCellData(cellValue, targetX, targetY, targetX - 1, targetY - 1);
}
}
// If we got a dot, store the value there.
// Do not forget to mark it with "!", so we can rescan it later.
if (isStringContained(targetContent, ".")) {
setCircuitCell(targetX, targetY, "!" + cellValue);
markThatStateChanged();
}
// If we got a "~", store the inverted value there.
// Do not forget to mark it with "!", so we can rescan it later.
if (isStringContained(targetContent, "~")) {
setCircuitCell(targetX, targetY, "!~(" + cellValue + ")");
markThatStateChanged();
}
// If we found a binary logical port with one of the values set and
// we can set the another value, do it. Use "%" and "&" to know which
// one was already defined.
// BTW, do not forget to mark it with "!", so we can rescan it later.
if ((targetContent.charAt(0) == '%' & sourceY == targetY - 1)
| (targetContent.charAt(0) == '&' & sourceY == targetY + 1))
{
setCircuitCell(targetX, targetY,
"!(" + cellValue + ")"
+ targetContent.charAt(1)
+ "(" + targetContent.substring(2) + ")");
markThatStateChanged();
}
// Found a binary logical port without any value setted, so set it.
// Use "%" and "&" to mark which one was setted.
if (isStringContained(targetContent, "OoAaXx")) {
setCircuitCell(targetX, targetY, (sourceY == targetY + 1 ? "%" : "&") + targetContent + cellValue);
markThatStateChanged();
}
// If we found an output, store the value there.
// Mark it with "$", so we will print it in the future.
if (isStringContained(targetContent, ":")) {
setCircuitCell(targetX, targetY, "$" + cellValue);
markThatStateChanged();
}
}
void setCircuitCell(int cellX, int cellY, String cellContents) {
circuitState.put(cellX * maxLines + cellY, cellContents);
}
void markThatStateChanged() {
finished = false;
}
boolean isStringContained(String searchingString, String searchTarget) {
return searchTarget.indexOf(searchingString) > -1;
}
}