Hangi değerin bir yoldaki hangi yönü temsil ettiğini belirleme


10

Önemli düzenleme: Daha önce, Örnek 1'de yanlış bir değer vardı. Düzeltildi.

Her hücrenin dört değerden birini içerdiği iki boyutlu bir dizi verilir.

Örnekler:

1 2 2 2 2 1        @ . .        X X V
1 3 1 4 1 4        e . @        I C V
2 3 1 3 4 2        H H @        X I V
1 4 4 2 1 3                     V C C
2 2 2 3 2 3                     X X X

Dört değer yön oklarını (yukarı, aşağı, sol ve sağ) temsil etse de, hangi değerin hangi yönü temsil ettiğini bilmiyorsunuz.

Başlangıç ​​veya bitiş noktalarının nerede olduğunu bilmeseniz de, yönlü oklar dizideki her hücreyi içeren kesintisiz bir yol oluşturur.

Dört değerin her birinin hangi yönü temsil ettiğini ve başlangıç ​​ve bitiş noktalarının nerede olduğunu belirleyen bir kod yazın.

A, B, C ve D değerlerini içeren bir dizi için kabul edilebilir bir dönüş değeri şöyle olacaktır:

{ up: A, down: C, left: D, right: B, start: [2, 0], end: [4, 2] }

Yolu her iki yönden de geçebildiğiniz için (baştan sona ve baştan sona), her zaman birden fazla doğru çözüm olacaktır ve ikiden fazla olabilir. Aldığınız girişlerin (yukarıdaki örneklerde olduğu gibi) her zaman en az bir doğru çözümü olduğunu varsayın. Birden fazla doğru çözümün olduğu durumlarda, doğru çözümlerden sadece birini döndürmek yeterlidir.

En kısa kod kazanır. Kazananı 7 gün veya 24 saat sonra, hangisi önce gelirse seçmeyeceğim.

Yukarıdaki örneklere çözümler ekliyorum, ancak yalnızca kodunuzu yazdıktan sonra bunları kontrol etmenizi öneririz:

Bir:

{yukarı: 3, aşağı: 1, sol: 4, sağ: 2, başlangıç: [0,0], bitiş: [2,5]}

İki:

{yukarı: '@', aşağı: 'e', ​​sol: '.', sağ: 'H', başlangıç: [1,1], bitiş: [0,0]}

Üç:

{yukarı: 'I', aşağı: 'V', sol: 'C', sağ: 'X', başlangıç: [0,2], bitiş: [4,2]}


1
"yolu her iki yönde de geçebilirsiniz" - yönler göreceli değil, mutlaksa, bu doğru değildir. Yol tarifleri mutlak veya göreli midir? Ayrıca, başlangıç ​​ve bitişin dizinin dışında olduğu biliniyor mu?
John Dvorak

@JanDvorak Başlangıç ​​ve bitiş noktaları dizi içindeki hücrelerdir. Yönlere gelince, her zaman bitişik bir hücreye (kuzey, güney, doğu veya batı) hareketi gösterdiğini varsayalım.
jawns317

Bu durumda bir yolu geriye doğru izlemek mümkün değildir. Her zaman birden fazla çözüm olacağının garantisini göremiyorum.
John Dvorak

1
"Her zaman bitişik bir hücreye hareketi gösterdiğini varsayarsak", ikinci örneğiniz hala geçerli mi? Bir şey eksik olabilir ama @ "sınırların dışına" gitmeden dört yönlerinden herhangi biri olamaz gibi görünüyor.
Nick Sarabyn

1
Örnek 1'in bir çözümü yoktur.
DavidC

Yanıtlar:


6

C #

EDIT: Bir bölüm ve biçimlendirme düzeltildi. Ve yardımcı sınıfı ekledi.

Bu golf kodu, 807 karakter

class M{public int c,x,y,u;}
void G(string[] z){
M K;int[]x={0,0,-1,1},y={-1,1,0,0},I={0,0,0,0};
string[]T={"Up","Down","Left","Right"};
int X,Y,R,n=0,H=z.Length,W=z[0].Length;W-=W/2;var D= string.Join(" ", z).Where(c=>c!=' ').Select(c=>new M(){c=c,x=n%W,y=n++/W}).ToList();n=0;var S=D.GroupBy(k=>k.c).ToDictionary(k=>k.Key,k =>n++);
for(;I[0]<4;I[0]++)for(I[1]=0;I[1]<4;I[1]++)for(I[2]=0;I[2]<4;I[2]++)for(I[3]=0;I[3]<4;I[3]++){
if ((1<<I[0]|1<<I[1]|1<<I[2]|1<<I[3])!=15)continue;
foreach (var Q in D){D.ForEach(p=>p.u=-1);R=1;K=Q;j:if((X=K.x+x[n=I[S[K.c]]])>=0&&X<W&&(Y=K.y+y[n])>=0&&Y<H&&(K=D[X+Y*W]).u<0){
K.u=1;if(++R==D.Count){Console.WriteLine("{4} Start({0}:{1}) End({2}:{3})",Q.x,Q.y,K.x,K.y,string.Join(", ",S.Select(k=>string.Format("{1}: '{0}'",(char)k.Key,T[I[k.Value]])).ToArray()));return;}goto j;}}}
}    

Üç test vakası için sonuçlar:

Aşağı: '1', Sağ: '2', Yukarı: '3', Sol: '4' Başlat (0: 0) Bitiş (5: 2)
Yukarı: '@', Sol: '.', Aşağı: ' e ', Sağ:' H 'Başlat (1: 1) Bitiş (0: 0)
Sağ:' X ', Aşağı:' V ', Yukarı:' I ', Sol:' C 'Başlat (0: 2) Bitiş (2: 4)

Bu "golf" olmadan ham kod, yaklaşık 4.000 karakter:

class Program
{
    static string[] input1 =  { "1 2 2 2 2 1",
               "1 3 4 4 1 4",       
               "2 3 1 3 4 2",
               "1 4 4 2 1 3",       
               "2 2 2 3 2 3"};

    static string[] input2 =  { "@ . .",
                                "e . @",       
                                "H H @",
               };

    static string[] input3 =  { "0 0 1",
                                "0 0 1",       
                                "3 2 2",
               };

    static void Main(string[] args)
    {
        Resolve(input1);
        Resolve(input2);
        Resolve(input3);
        Console.ReadLine();
    }


    class N { public int c; public int x, y, i, u; }

    static void Resolve(string[] input)
    {
        int[] ox = { -1, 1, 0, 0 }, oy = { 0, 0, -1, 1 }, I = { 0, 0, 0, 0 };
        string[] TXT = { "Left", "Right", "Up", "Down" };
        int X, Y, R, n = 0, H = input.Length, W = input[0].Length;
        W -= W / 2;
        N K = null;
        var data = string.Join(" ", input).Where(c => c != ' ').Select(c => new N() { c = c, x = (n % W), y = (n / W), i = n++, u = -1 }).ToList();
        n = 0;
       var S = data.GroupBy(k => k.c).ToDictionary(k => k.Key, k => n++);

        for (; I[0] < 4; I[0]++)
            for (I[1] = 0; I[1] < 4; I[1]++)
                for (I[2] = 0; I[2] < 4; I[2]++)
                    for (I[3] = 0; I[3] < 4; I[3]++)
                    {
                        if (((1 << I[0]) | (1 << I[1]) | (1 << I[2]) | (1 << I[3])) != 15) continue;
                        foreach(var Q in data)
                        {
                            data.ForEach(p => p.u = -1);
                            R = 0;
                            K = Q;
                            while (K != null)
                            {
                                n = I[S[K.c]];
                                X = K.x + ox[n];
                                Y = K.y + oy[n];
                                if (X >= 0 && X < W && Y >= 0 && Y < H)
                                {
                                    n = X + Y * W;
                                    if (data[n].u < 0)
                                    {
                                         data[n].u = K.i;
                                         K = data[n];
                                        R++;
                                        if (R == data.Count - 1)
                                        {
                                            Console.WriteLine();
                                            Console.WriteLine("Start({0}:{1}) End({2}:{3})", Q.x, Q.y, K.x, K.y);
                                            Console.WriteLine(string.Join(", ", S.Select(k => string.Format("'{0}': {1}", (char)k.Key, TXT[I[k.Value]])).ToArray()));
                                            Action<N> Write = null;
                                            Write = (k) =>
                                             {
                                                 if (k.u != -1)
                                                 {
                                                     Write(data[k.u]);
                                                 }
                                                 Console.Write(string.Format("({0}:{1}){2}", k.x, k.y, k == K ? "\n" : " => "));
                                             };

                                            Write(K);
                                            return;
                                        }
                                        continue;
                                    }
                                }
                                K = null;
                            }
                        }
                    }
        Console.WriteLine("Solution not found");
    }
 }
}

Bunlar üç örneğin sonuçlarıdır:

Çözüm bulunamadı

Başlat (1: 1) Son (0: 0) '@': Yukarı, '.': Sol, 'e': Aşağı, 'H': Sağ

(1: 1) => (0: 1) => (0: 2) => (1: 2) => (2: 2) => (2: 1) => (2: 0) => ( 1: 0) => (0: 0)

Başlangıç ​​(0: 0) Bitiş (1: 1) '0': Sağ, '1': Aşağı, '3': Yukarı, '2': Sol

(0: 0) => (1: 0) => (2: 0) => (2: 1) => (2: 2) => (1: 2) => (0: 2) => ( 0: 1) => (1: 1)


Bu bir kod golf yarışması olduğu için kodunuzu golf oynamak isteyebilirsiniz.
Timtech

Blau

Tamam, acele yok :) Sadece bazı insanlar golf kodu olmadan yeni bir kullanıcı görüyor ve aşağı iniyor.
Timtech

2
Bu benim ilk kez ... ama ben henüz golf değil tavsiye ... matemathica kodunu yenmez düşünüyorum ... :)
Blau

Bu soruya herhangi bir cevap beceri gerektirir. +1
Timtech

5

Mathematica 278

"Netlik" için boşluklar eklendi

k@l_ := (s = #~Join~-# &@{{1, 0}, {0, 1}};
         f@r_ := Flatten[MapIndexed[#2 -> #2 + (#1 /. r) &, l, {2}], 1];
         g     = Subgraph[#, t = Tuples@Range@Dimensions@l] & /@ 
                       Graph /@ f /@ (r = Thread[# -> s] & /@ Permutations[Union @@ l]);
        {t[[#]] & /@ Ordering[Tr /@ IncidenceMatrix@g[[#]]][[{1, -1}]], r[[#]]} & @@@ 
                                                                 Position[PathGraphQ /@ g, True])

Oturum ve Çıktı:

 l = l1 = {{1, 2, 2, 2, 2, 1}, {1, 3, 1, 4, 1, 4}, {2, 3, 1, 3, 4, 2}, 
            {1, 4, 4, 2, 1, 3}, {2, 2, 2, 3, 2, 3}}; ;
 k@l1
 {{{{1, 1}, {3, 6}}, 
    {1 -> {1, 0}, 2 -> {0, 1}, 3 -> {-1, 0},  4 -> {0, -1}}}}

Hangi başlangıç ​​sembolü, bitiş noktası ve her sembolle ilişkili geçiş kurallarıdır.

Yönlendirilmiş grafiği göstermek için tamamlayıcı kod:

sol = sg[[Position[PathGraphQ /@ sg, True][[1, 1]]]];
Framed@Graph[
  VertexList@sol,
  EdgeList@sol,
  VertexCoordinates -> VertexList@sol /. {x_, y_} :> {y, -x},
  VertexLabels -> MapThread[Rule, {VertexList@sol, Flatten@l}], 
  EdgeShapeFunction -> GraphElementData["FilledArcArrow", "ArrowSize" -> 0.03],
  ImagePadding -> 20]

Mathematica grafikleri


2

Mathematica (151)

L = {{1, 2, 2, 2, 2, 1}, {1, 3, 1, 4, 1, 4}, {2, 3, 1, 3, 4, 2}, 
   {1, 4, 4, 2, 1, 3}, {2, 2, 2, 3, 2, 3}};

PathGraphQ@#~If~Print@{TopologicalSort[#]〚{1,-2}〛,r}&@
Graph@Flatten@MapIndexed[#2->#2+(#/.r)&,L,{2}]~Do~{r,
Thread[Union@@L->#]&/@{-1,0,1}~Tuples~{4,2}}

Başlangıç ​​noktası, bitiş noktası ve geçiş kurallarını döndürür. İlk dizin satır, ikincisi sütun

{{{1,1},{3,6}},{1->{1,0},2->{0,1},3->{-1,0},4->{0,-1}}}

Kodumun bile ile çalıştığını unutmayın {-1,0,1}~Tuples~{4,2}. Hızlandırmak için kullanabilirsiniz Permutations@{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}.


0

APL (207)

Mathematica'dan daha kısa yapamadım, çünkü TopologicalSort ve benzeri açıdan mantık yapamadım. Daha akıllı insanlar daha fazla sıkmak için bekliyoruz.

golfed:

{u←∪,t←⍵⋄q r←↑(0≠+/¨r)/⊂[2]p,⍪r←{m←,⍵[u⍳t]⋄v r←⊂[1]⊃{{(↑⍴∪⍵),⊂(↑⍵)(↑⌽⍵)}n↑{3::⍬⋄i←↑⌽⍵⋄⍵,i+i⌷m}⍣n,⍵}¨⍳n←↑⍴,t⋄↑(v=n)/r}¨p←⊂[2]{1≥⍴⍵:⊃,↓⍵⋄⊃⍪/⍵,∘∇¨⍵∘~¨⍵}d←¯1 1,¯1 1×c←¯1↑⍴t⋄⊃('←→↑↓',¨u[q⍳d]),{1+(⌊⍵÷c)(c|⍵)}¨r-1}

Ungolfed:

D←{⎕ML ⎕IO←3 1
    pmat←{1≥⍴⍵:⊃,↓⍵⋄⊃⍪/⍵,∘∇¨⍵∘~¨⍵}   ⍝ utility: permutations of the given vector
    u←∪,t←⍵                    ⍝ the 4 unique symbols in t←⍵
    n←↑⍴,t                     ⍝ number of elements in t
    d←¯1 1,¯1 1×c←¯1↑⍴t        ⍝ the four ∆i (+1, -1, +cols, -cols)
    p←⊂[2]pmat d               ⍝ list of permutations of the four ∆i
    r←{                        ⍝ for each permutation ⍵∊p (=interpretation of the 4 symbols)
        m←,⍵[u⍳t]              ⍝ (ravelled) t-shaped matrix of ∆i, using interpretation ⍵
        v r←⊂[1]⊃{             ⍝ for each starting index ⍵∊⍳n
            v←n↑{              ⍝ trail of visited cells after n steps 
                3::⍬           ⍝ if index out of bounds return empty list
                i←↑⌽⍵          ⍝ take last visited index
                ⍵,i+i⌷m        ⍝ follow the directions and add it to the list
            }⍣n,⍵
            (↑⍴∪v),⊂(↑v),↑⌽v   ⍝ number of unique cells, plus start/end indices
        }¨⍳n
        ↑(v=n)/r               ⍝ 1st couple of start/end indices to visit all cells (if any)
    }¨p
    q r←↑(0≠+/¨r)/⊂[2]p,⍪r     ⍝ select first perm. and start/end indices to visit all cells
    ⊃('←→↑↓',¨u[q⍳d]),{1+(⌊⍵÷c)(c|⍵)}¨r-1   ⍝ return char mapping and start/end indices
}

Örnekler:

(Endeksler 1'den başlar)

     D⊃'122221' '131414' '231342' '144213' '222323'
 ←  4 
 →  2 
 ↑  3 
 ↓  1 
 1  1 
 3  6 
     D⊃'@..' 'e.@' 'HH@'
 ←  . 
 →  H 
 ↑  @ 
 ↓  e 
 2  2 
 1  1 
     D⊃'XXV' 'ICV' 'XIV' 'VCC' 'XXX'
 ←  C 
 →  X 
 ↑  I 
 ↓  V 
 3  1 
 5  3 
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.