Çeviri Tablosunu Bulun


17

İki dize verildiğinde, ikisi arasında çeviri tablosunu ( ikame şifresi ) bulun , eğer çeviri mümkün değilse false çıktısını alın. Cevap en aza indirilmeli ve soldan sağa doğru oluşturulmalıdır. Sözcükler arasında çevrilecek ilk karakter, çeviri tablosundaki ilk karakter olmalıdır. Buna ek olarak, çevrilmemiş herhangi bir harf (başlangıçtaki ile aynı yerde), çeviri tablosunda OLMAMALIDIR.

Muhtemelen en kolay şekilde örneklerle tanımlanmıştır:

Geçerli Vakalar

"bat", "sap" => ["bt","sp"]

Siparişe dikkat edin, çıktısı ["tb","ps"]bu zorluk için geçerli değildir.

"sense", "12n12" => ["se","12"]

Bire nbir ilişki olduğu için nasıl çevrilmediğine dikkat edin .

"rabid", "snail" => ["rabd","snal"]

Bire ibir ilişki olduğu için nasıl çevrilmediğine dikkat edin .

"ass", "all" => ["s","l"]

Bir o, aynı kalır, dahil değildir seşleme yapabilirsiniz ldesen maçı nedeniyle.

"3121212", "ABLBLBL" => ["312","ABL"]

Mükemmel desen eşleşir.

Falsy Kılıfları

"banana", "angular" => false

(aynı uzunlukta değil, imkansız).

"animal", "snails" => false

(her karakter yalnızca çevirinin her iki tarafında da kullanılabilir).

"can","cnn" => false

(n dolaylı olarak çeviride kullanılır, bu nedenle n-> a ile bir çeviri tablosu tanımlamak geçersiz olacaktır)

Nitekim, [aimal,sails]geçersiz bir cevap, bu falsy yapma.

"a1", "22" => false

Bkz. "Uyarılar", bu falsy olarak listelenir. Çünkü bu durumda, bu kadar ave 1her ikisine de eşleyemezsiniz 2. (Her karakter yalnızca çevirinin her iki tarafında YALNIZCA kullanılabilir).


Bu cevap iyi bir ölçüt gibi görünüyor: /codegolf//a/116807/59376

Listelenmemiş iki kelime çiftinin işlevselliği hakkında sorularınız varsa, bu uygulamaya erteleyin.


G / Ç kuralları

  • Giriş, 2 elemanlı bir dizi veya 2 ayrı giriş olarak olabilir.
  • Çıktı, gösterdiğim gibi, bir dizi veya satırsonu / boşluk olarak sınırlandırılmış olabilir.
  • Yanlış çıktı 0, -1 veya yanlış olabilir. Hata / Boş çıktı da gayet iyi.
  • Bunu garanti aeşit olmaz bve ne ade bboş olacaktır.
  • ave bsadece yazdırılabilir ASCII harf dizileri.

Uyarılar

  • Tercümeler soldan sağa yapılmalıdır, bakınız örnek 1.
  • Aynı kalan karakterlerin çıktısını almamalısınız.
  • Programınız sadece iki dizeleri alabilir ave b.
  • Her karakter çevirinin sadece iki tarafında kullanılabilir. Bu çeviriye kılan snailsetmek animalsimkansız.
  • Yinelemeli değiştirmeler yapılmamalıdır. Özyinelemeli değiştirme örneği: "a1","22"->[a1,12]burada a ilk olarak 1 ile değiştirilir, ardından her iki sonuç 1 de 2 ile değiştirilir. Bu doğru değil, tüm çevirilerin birbirinden bağımsız olarak gerçekleştiğini varsayalım, yani bu yanlıştır. Anlamı: [a1,12] 'nin çeviri tablosuyla "a1" 12 olarak değerlendirilir (22 değil)

Bu "çeviriyi" basit bir ikame şifresi olarak etiketlemek amacı açıklığa kavuşturmaya yardımcı olabilir.
Greg Martin

İlişkilendirilebilir dizilere çıktı olarak izin veriliyor mu? Beni biraz bayt kurtarabilir
Jörg Hülsermann

@ JörgHülserman Buna izin vermenin sonuçlarından tam olarak emin değilim, belki farkı görebilmem için 2 versiyon yapalım? Zorluğa zararlı olmadığını düşünürsem düzenlerim.
Sihirli Ahtapot Urn

Benim ilk çözüm dize olarak bakın ve ikincisi çıktı olarak ilişkisel bir dizi vardır
Jörg Hülsermann

@ JörgHülsermann ahhh ... Şimdi nasıl kullandığınızı görüyorum, sanırım buna izin vermeyeceğim, tüm diller karma benzeri yapıları desteklemiyor.
Sihirli Ahtapot Urn

Yanıtlar:


7

JavaScript (ES6), 128 bayt

f=
(s,t)=>!t[s.length]&&[...s].every((c,i)=>n[d=t[i]]==c||d&&!m[c]&&!n[d]&&(n[m[c]=d]=c,c==d||(a+=c,b+=d)),m={},n={},a=b='')&&[a,b]
<div oninput=o.textContent=f(s.value,t.value)><input id=s><input id=t><pre id=o>


Çalışmıyor assve allolmalı s,l.
Sihirli Ahtapot Urn

Evet, bu pasaj trippin ', ayrıca doğrulandı, sorun değil.
Sihirli Ahtapot Urn

1
@carusocomputing Değişken ad çakışmasıydı - şimdi düzeltildi. Bunun için üzgünüm.
Neil

7

JavaScript (ES6), 108 107 105 106 bayt

Düzenleme : Bu gibi "22" / "a1"yanlış girişleri desteklemek için sabit.


0İki dizeden birini veya bir diziyi döndürür .

f=(a,b,x)=>[...a].some((c,i)=>d[C=b[i]]?d[C]!=c:(d[C]=c)!=C&&(s+=c,t+=C,!C),s=t='',d=[])?0:x||f(b,a,[s,t])

Biçimlendirilmiş ve yorumlanmış

f = (                       // given:
  a,                        // - a = first string
  b,                        // - b = second string
  x                         // - x = reference result from previous iteration,
) =>                        //       or undefined
  [...a].some((c, i) =>     // for each character c at position i in a:
    d[                      //   if we already have a translation
      C = b[i]              //   of the character C at the same position in b,
    ] ?                     //   then:
      d[C] != c             //     return true if it doesn't equal c
    :                       //   else:
      (d[C] = c) != C &&    //     store the translation C -> c in the dictionary
      (                     //     if the characters are different:
        s += c, t += C,     //       append them to the translation strings s and t
        !C                  //       return true if C is undefined
      ),                    //
    s = t = '', d = []      //   initialize s, t and d  
  ) ?                       // if some() returns true:
    0                       //   there was a translation error: abort
  :                         // else:
    x ||                    //   if this is the 2nd iteration, return x
    f(b, a, [s, t])         //   else do a recursive call with (b, a)

Test senaryoları


f('22')('a1')aynı zamanda sahte olmalıdır.
Neil

Umarım bu sefer doğru anladım.
Arnauld

1
Daha kısa bir şeyi basitleştirmek için bugfix'iniz ortaya çıktığında her zaman kullanışlıdır!
Neil

7

PHP> = 7,1, 130 Bayt

@Titus tarafından kaydedilen 18 bayt

for([,$x,$y]=$argv;a&$o=$y[$i];)$o==($p=$x[$i++])?:$k[$c[$p]=$o]=$p;echo$y==strtr($x,$c)&$x==strtr($y,$k)?join($k)." ".join($c):0;

testcases

Expanded

for([,$x,$y]=$argv;a&$o=$y[$i];)
$o==($p=$x[$i++])?:$k[$c[$p]=$o]=$p; # if char string 1 not equal char string 2 make key=char1 value=char2 and key array
echo$y==strtr($x,$c) # boolean replacement string 1 equal to string 2
    &$x==strtr($y,$k) # boolean replacement string 2 equal to string 1
    ?join($k)." ".join($c) # output for true cases
:0; #Output false cases

PHP> = 7,1, 148 Bayt

yanlış çıktı için 0 yazdırır String olarak true

for([,$x,$y]=$argv;a&$o=$y[$i];$i++)$x[$i]==$o?:$c[$x[$i]]=$o;echo$y==strtr($x,($f=array_flip)($k=$f($c)))&$x==strtr($y,$k)?join($k)." ".join($c):0;

testcases

Expanded

for([,$x,$y]=$argv;a&$o=$y[$i];$i++)
$x[$i]==$o?:$c[$x[$i]]=$o; # if char string 1 not equal char string 2 set key=char1 value=char2
echo$y==strtr($x,($f=array_flip)($k=$f($c))) # boolean replacement string 1 equal to string 2
&$x==strtr($y,$k) # boolean replacement string 2 equal to string 1
    ?join($k)." ".join($c) # output for true cases
:0; #Output false cases

PHP> = 7,1, 131 Bayt

İlişkisel dizilere izin verilirse ikinci yanıt kısa devre yapılabilir

dize yerine ilişkisel dizi olarak false Çıktısı için 0 yazdırır

for([,$x,$y]=$argv;a&$o=$y[$i];$i++)$x[$i]==$o?:$c[$x[$i]]=$o;print_r($y==strtr($x,($f=array_flip)($f($c)))&$x==strtr($y,$k)?$c:0);

testcases

PHP> = 7,1, 227 Bayt

yanlış için 0 yazdırır

[,$x,$y]=$argv;echo strlen($x)==strlen($y)?strtr($x,$c=array_filter(($f=array_flip)($z=$f(array_combine(($p=str_split)($x),$p($y)))),function($v,$k){return$k!=$v;},1))==$y&$x==strtr($y,$z)?join(array_keys($c))." ".join($c):0:0;

testcases

Expanded

[,$x,$y]=$argv; # 
echo strlen($x)==strlen($y) #compare string lengths
?strtr($x,  # replace function
$c=array_filter( # filter 
($f=array_flip)($z=$f( # # remove doubles like in testcase: a1 => 22
    array_combine(($p=str_split)($x),$p($y))  # replacement array keys string 1 values string 2 
))
    ,function($v,$k){return$k!=$v;},1)) # remove all keys that equal to values in array
    ==$y # boolean replacement string 1 equal to string 2
&$x==strtr($y,$z) # boolean replacement string 2 equal to string 1        
?join(array_keys($c))." ".join($c) # output for true cases
    :0 # Output if replacement from string 1 is not equal to string 2
:0; #Output for different lengths

1
@carusocomputing İltifatınız için teşekkür ederim. Biraz hile unuttum. Burada benden daha iyi oldukları birçok insan olduğunu biliyorum
Jörg Hülsermann

2
+ 1'i çözüm bulma konusunda kesinlikle iyisiniz ama array_values()içeride join()tamamen işe yaramaz ve düşebilir.
Christoph

1
Bu, a1 22 => falsetest senaryosunu geçemez. Ayrıca, ilk programınız çevrimiçi test cihazında çalışmıyor gibi görünüyor.
mbomb007

1
Kapa çeneni. Harikulade.
Titus

1
Yüzgeçler gidebilir: Kaydet 18 ile bayt ($p=$x[$i])==$o?:$k[$c[$p]=$o]=$p;döngü içinde ve $y==strtr($x,$c)ilk test için.
Titus

5

Jöle , 18 bayt

ẠaQ⁼µ€Ạ
z0EÐḟQZẋÇ$

Bir liste alarak adlandırılmamış monadik bağlantı (tek giriş işlevi): döndürür:
falsey durumlarda boş bir liste; veya
doğru durumlarda iki karakter listesi içeren bir liste.

Çevrimiçi deneyin! (altbilgi, sıkıştırılmış bir sunum yazdırmaktan kaçınmak için listeyi bir boşlukla böler)
... veya bir test takımına bakın .

Nasıl?

ẠaQ⁼µ€Ạ - Link 1, valid?: mapping list
    µ€  - perform the code to the left for €ach mapping entry
Ạ       -     none of mapping entry falsey? (this & Main's z0 handle unequal input lengths)
  Q     -     deduplicate mapping entry
   ⁼    -     is equal to mapping list? (non-vectorising)
 a      -     and
      Ạ - none falsey (both mapping lists must pass that test)
        - The whole function returns 1 if the mapping list is acceptable, 0 if not

z0EÐḟQZẋÇ$ - Main link: list of strings
z0         - transpose with filler 0 (unequal lengths make pairs containing zeros)
   Ðḟ      - filter discard:
  E        -     all equal? (removes the untranslated character pairs)
     Q     - deduplicate (removes the repeated translation pairs)
      Z    - transpose (list of pairs to pair of lists)
         $ - last two links as a monad:
       ẋ   -     repeat list this many times:
        Ç  -         call last link (1) as a monad

5

Retina , 194 191 185 229 225 241 bayt

.+
$&;$&
+`^\w(\w*;)\w
$1
^;\w.*|.+;;.*|;;

^((.)*)(.)(.*;(?<-2>.)*(?(2)(?!)))\3
$1$4
+`((.)(.)*)\2((.)*;.*(.)(?<-3>.)*(?(3)(?!)))\6((?<-5>.)*(?(5)(?!)))$
$1$4$7
^(.)*(.)(.)*(\2)?.*;(?<-1>.)*(?(1)(?!))(.)(?<-3>.)*(?(3)(?!))(?(4)(?!\5)|\5).*

Çevrimiçi deneyin!

Girdi alır - ;ayrılmıştır. Çıktı da ;ayrılır. Yanlış girişler boş çıkışlarla belirtilir.

Bunun acı verici olduğunu biliyorum, hala baytları azaltmaya çalışıyorum. Bu baytların çoğu yanlış girdileri silmeye gider.

Düzenlemeler

  • Programımla ilgili önemli bir kusurum olduğu ortaya çıktı. Şimdi düzeltildi, ancak 40 baytın üzerinde bir maliyetle.

  • Programımın girişi a1;22yanlış bildirmediği başka bir hata bulundu , ancak düzelttikten sonra programı 250 baytın altında tutabildim

açıklama

(birazdan daha ayrıntılı bir açıklama gelecek)

Önce dizeleri uzunlukları olmadığını kontrol etmek zorunda ave baynı veya değil. Değilse, her şeyi sileriz.

Bazı uzunluk testleri yaparken girişi korumak için çoğaltır.

.+                      Matches everything
$&;$&                   $& indicates the match, so $&;$& will duplicate the match and separate it with a semi-colon

Şimdi bir döngüde, dizelerden biri boşalana kadar ailk karakterini ve ilk karakterini bsiliyoruz.

+`                     Repeatedly (until no more substitutions could be made) replace
  ^\w                   A word character (letter or number) at the beginning
     (\w*;)             Capture Group 1: matches any number of word characters and a semicolon
           \w           And a word character after the semi-colon
                       with
$1                      The result of the first capture group

Şimdi "desen alanı" için olasılıklar var.

  • ;;abc Her iki tel de eşit uzunluktadır
  • def;;abc a daha uzun b
  • ;def;abc b daha uzun a

Dizeler aynı uzunlukta değilse (girişi senaryo 2 ve 3) şimdi girişi boşaltmamız gerekir. Aşağıdaki bu ikame budur. Senaryo 2 ve 3 ile eşleşen metni kaldırır.

^;\w.*|.+;;.*|;;

Bu, dizelerde ave harflerinde dönüştürülmeyen karakterleri kaldırır b. abc;1b2=>ac;12

^((.)*)(.)(.*;(?<-2>.)*(?(2)(?!)))\3
$1$4

Bundan sonra, yinelenen karakterleri kaldırmamız gerekiyor. sese;1212=> se;12, ancak bu gibi girişleri koruraba;123

+`((.)(.)*)\2((.)*;.*(.)(?&lt;-3&gt;.)*(?(3)(?!)))\6((?&lt;-5&gt;.)*(?(5)(?!)))$
$1$4$7

Son olarak, aba;123veya gibi farklı karakterlerle eşleşen yinelenen karakterler varsa girdiyi sileriz a1;22.

^(.)*(.)(.)*(\2)?.*;(?.)*(?(1)(?!))(.)(?.)*(?(3)(?!))(?(4)(?!\5)|\5).*

Ve son olarak, yinelenen karakterleri kaldırın.


Bu dengeleme gruplarını kullanarak görüyorum!
Neil

@Neil Gerçekten! Ben de (?(1)(?!))cevabınızdan öğrendim :) kullandım
Kritixi Lithos

I wonder whether it would be shorter to remove duplicates first and then validate the remaining sets - there should only be one of each letter remaining on each side of the ;.
Neil

@Neil I found an error with my code experimenting with that. I will look further into it in the morning.
Kritixi Lithos

4

Jelly, 28 26 bytes

QL$€⁼L€
EÐḟQZK0Ç?
ZÇ0L€E$?

Try it online!

QL$€⁼L€      Checks validity of mapping
QL$€          number of unique characters in mapping
    ⁼         equals
     L€       number of characters in mapping

EÐḟQZK0Ç?  Writes valid mapping or 0
EÐḟ           filter maps where a = b
   Q          filter duplicate maps
    Z         zip by column [["ac"],["bd"]] => ["ab","cd"]
     K0Ç?   print if valid map, else print 0

ZÇ0L€E$?      main link: takes an array of 2 strings
Z              zip by column: ["ab", "cd"] => [["ac"],["bd"]]
 Ç     ?       print mapping if
   L€E$         all pairs are same length (returns 0 if initial strings were
  0             else 0

1
Welcome to PPCG! How the hell do you already know Jelly with only 21 points? Very impressive!
Magic Octopus Urn

2
Thanks. Looked around the site a bit and it seemed like a neat language to learn.
layagyasz

05AB1E is another easy and fun one to try out.
Magic Octopus Urn

3

Ruby, 133 bytes

->a,b{a.size!=b.size||(m=a.chars.zip b.chars).any?{|i,j|m.any?{|k,l|(i==k)^(j==l)}}?0:m.select{|x,y|x!=y}.uniq.transpose.map(&:join)}

Try it online!

More readably:

->a, b{
    # Pair the letters in each string - [AB, AB, AB,...]
    pairs = a.chars.zip(b.chars)

    # If there's any combination of two pairs that share one character but not both,
    # or if the strings have different lengths, then the input's invalid.
    if a.size != b.size || pairs.any?{|i,j| pairs.any? {|k, l| (i==k)!=(j==l) }} 
        return 0 # 0 isn't actually falsy in Ruby, but this challenge allows it anyway
    end
    return pairs.select{|x,y| x != y} # Remove unchanged letters
                .uniq                 # Remove duplicates
                .transpose            # Change [AB, AB, AB] form to [AAA, BBB] form.
                .map(&:join)          # Convert the arrays back into strings
}

Just for kicks, here's an 84 byte version in Goruby, which is Ruby, but with a golf flag set when compiling the interpreter. Among other things, it allows you to abbreviate method calls to their shortest unique identifier.

->a,b{a.sz!=b.sz||(m=a.ch.z b).ay?{|i,j|m.y?{|k,l|(i==k)^(j==l)}}?0:m.rj{|x,y|x==y}.u.tr.m(&:j)}

Why not post a second answer with the Goruby implementation? Is it not an accepted golfing language?
Magic Octopus Urn

@carusocomputing It totally is; it just seemed to me like it didn't merit its own answer - it's exactly the same as my main answer, just with method names abbreviated. Perhaps if I find a way to take advantage of more of Goruby's differences I'll post a separate answer.
Tutleman

3

Python 2, 198,193,189,182,179,175,169,165 bytes

def f(a,b):
 r=([""]*2,0)[len(a)!=len(b)]
 for u,v in zip(a,b):
	if r:
		q,w=r
		f=q.find(u)
		if u!=v:r=(([q+u,w+v],r)[f>-1 and w[f]==v],0)[f<0 and v in w]
 print r

Try it online!

  • -4 bytes! thanks to mbomb007 for suggesting the use of tab instead of space.

  • modified the input format, again thanks to mbomb007.


what do you mean by that? please stop making unwanted edits which doesnt add any value to answer!
Keerthana Prabhakaran

tab saved around 4 bytes! Thank you!
Keerthana Prabhakaran


And I made your program have each test case on a single line, which is extremely helpful to anyone testing your program.
mbomb007

I'd would have better if you could have mentioned that in your edit comment!
Keerthana Prabhakaran

3

Python 3.6, 211 185 181 178 bytes

Exits with an error for falsy results.

def f(x,y,d={}):
    for a,b in zip(x,y):1/(a not in d or b==d[a]or len(x)-len(y));d[a]=b;1/([*d.values()].count(b)<2)
    return map(''.join,zip(*[x for x in d.items()if x[0]!=x[1]]))

This requires Python 3.6, which you can run in a shell here.

You can test it without the correct output ordering on TIO here. (TIO doesn't have 3.6).

Ungolfed:

from collections import*
d=OrderedDict()                     # keep order
x,y=input()
if len(x)!=len(y):1/0               # equal lengths
for a,b in zip(x,y):
    if a in d and d[a]!=b:1/0       # no duplicate keys
    else:d[a]=b
    if d.values().count(b)>1:1/0    # no duplicate values
print map(''.join,zip(*[x for x in d.items()if x[0]!=x[1]])) # format, no no-ops

If only order didn't matter...


Shouldn't a1,12 return a1,12 instead of False? Under the Caveats section it is said that "a1" with translation table of [a1,12] evaluates to 12.
fergusq

1
Well, the program in your TIO link returns False. 1a 21 would also be wrong, as the oeder has to be preserved.
fergusq

@fergusq Fixed. But notice that you have a typo in your comment if that's the test case you're referring to, since you said a1,12 instead of a1,22.
mbomb007

I misunderstood you. You referred to the Caveats section in your question edit, but the Caveats section actually handles a different case – not the bijection rule. That confused me.
fergusq

It handles a different rule, but it still says that the result of that test case is false, which is what mattered.
mbomb007

2

Röda, 108 119 bytes

{c=[{_<>_|[[_,_]]|orderedUniq}()]d=[]e=[]c|_|{{d+=a;e+=b}if[a!=b]}for a,b[d,e]if[0,1]|{|n|c|[_[n]]|sort|count|[_2=1]}_}

Try it online!

This is a function that takes two lists of characters from the stream and pushes two lists to the stream.

This could be sorter if I was allowed to return pairs.

Explanation (out-dated):

{
    c=[{
        _<>_|       /* pull two lists and interleave them */
        [[_,_]]|    /* "unflat", create lists from pairs */
        orderedUniq /* remove duplicates */
    }()]            /* c is a list of the pairs */
    d=[]
    e=[]
    c| /* push the pairs to the stream */
    _| /* flat */
    {  /* for each pair (a, b): */
        { /* if a != b (remove "1-to-1 relations"):  */
            d+=a;
            e+=b
        }if[a!=b]
    }for a,b
    /* return d and e if no character is mapped to more than one character */
    [d,e]if c|[_[0]]|sort|count|[_2=1]
}

Here's an underscore solution that contains no variables (114 bytes):

{[[{_<>_}()|[[_,_]]|unorderedUniq]]|[[_()|_|[_]if[_1!=_2]],[_1()|_|[_2]if[_1!=_2]]]if[[_1()|_][::2],[_1()|_][1::2]]|[sort(_)|count|[_2=1]]}

That's a lot of underscores.


What does the <> do?
Kritixi Lithos

@KritixiLithos It's the interleave operator. a() <> b() is same as interleave([a()], [b()]) (or just interleave(a, b), if a and b are arrays).
fergusq

This fails the a1 22 => false test case. "all translations occur independent of each other, meaning this is falsy."
mbomb007

@mbomb007 I don't quite understand what you say? Do you mean it has to be a bijection, ie. no two characters must be mapped to a same character?
fergusq

Yes. That's what the question says. (Each character can only be used ONCE on each side of the translation)
mbomb007

1

AWK, 140 bytes

BEGIN{RS="(.)"}RT~/\W/{S=1}RT~/\w/&&S{if(RT!=x=A[++b]){if(B[z=RT]==""){B[z]=x
c=c x
d=d z}a=B[z]!=x?0:a}}!S{A[++a]=RT}END{if(a==b)print c,d}

Usage: Place code in FILE then:

awk -f FILE <<< "string1 string2"

The input strings need to be whitespace separated.

The output is empty if they fail, or 2 strings separated by a space.


1

k, 28 bytes

{$[(y?y)~x?x;+?(~=/)#x,'y;]}

Explanation:

{                          } /function that takes in two strings, x and y
 $[         ;            ;]  /if statement (to check if there is a mapping)
         x?x                 /first index of [each letter in x] in x
   (y?y)                     /first index of [each letter in y] in y
        ~                    /make sure they match
                     x,'y    /zip together the two strings
               (~=/)#        /remove equal pairs
              ?              /unique pairs only
             +               /transpose ("unzip", in a way)

1

APL (Dyalog) with AGL, 22 bytes

{≡/⍳⍨¨⍺⍵:↓⍉↑∪⍺(≠é,¨)⍵}

Try it online!

{} anonymous function:

 If…

  ⍺⍵ the arguments

  ⍳⍨¨ when self-indexed (i.e. the first occurrences of their elements in themselves)

  ≡/ are equivalent

: then:

  ⍺()⍵ apply the following tacit function to the arguments:

    concatenate corresponding elements (errors on mismatching lengths)

   é then filter by (é is just the primitive function /)

    where the strings are different

   unique (remove duplicates)

  ↓⍉↑ transpose list-of-pairs to pair-of-lists (lit. mix into table, transpose table, split into lists)

 else, do nothing


1
patiently awaits the explanation of this answer :P
Magic Octopus Urn

1
@carusocomputing I'm on it.
Adám

@carusocomputing OK?
Adám

I missed that reply, sorry! ↓⍉↑ still has me a little confused.
Magic Octopus Urn

1
@carusocomputing Maybe this helps? Note that in APL and J, a matrix is not the same as a list of lists.
Adám

0

CJam, 38 bytes

{_:,~={1\/;}:K~z{)\c=!},L|z_{_L|=K}%;}

Input and output are arrays on the stack.


0

PHP (>=7.1), 165 bytes

for([,$x,$y]=$argv;a&$c=$x[$i];$t[$c]=$d)$z+=($d=$y[$i++])&&$d==($t[$c]??$d);foreach($t as$a=>$b)$a==$b?:$r[$a]=$b;print_r($z<$i|array_unique($r)<$t||a&$y[$i]?0:$t);

prints 0 for falsy, associative array else. Run with -r or test it online.

breakdown

for([,$x,$y]=$argv;         # import arguments to $x and $y
    a&$c=$x[$i];            # loop through $x
    $t[$c]=$d)                  # 2. add pair to translation
$z+=                            # 1. increment $z if
    ($d=$y[$i++])&&             # there is a corresponding character in $y and
    $d==($t[$c]??$d);           # it equals a possible previous replacement
                            # remove identities from translation
foreach($t as$a=>$b)$a==$b?:$r[$a]=$b;
print_r(
    $z<$i                   # if not all tests passed
    |array_unique($t)<$t    # or there are duplicates in the translation
    ||a&$y[$i]              # or $y has more characters
    ?0                      # then print 0
    :$r                     # else print translation
);

Are associative arrays as Output allowed? Could you please add that it works above version 7.1
Jörg Hülsermann

@JörgHülsermann Output can be as an array or ..., so I´d say yes. Current PHP version is implicit for all my postings; but if I find something important to edit, I´ll add the version.
Titus

The valid cases shows only one meaning of array output. If associative arrays are also allowed I can save a few bytes. If it is allowed and array_unique($r)!=$r is in every case array_unique($r)<$r I will upvote your post alone for this trick. In the moment I am searching for an explanation
Jörg Hülsermann

@JörgHülsermann array_unique($t)<$t (had to change that because can to cnn is invalid) works, because array comparison (unlike string comparison) compares lengths before anything else.
Titus

The test can to cnn cost me 17 Bytes Forget my suggestion
Jörg Hülsermann
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.