Otrzymasz ciąg do zrobienia i zaczynając od pustego ciągu, spraw, aby wykorzystywał koszty dołączania i klonowania

17

Twoim zadaniem jest utworzenie podanego ciągu docelowego. Począwszy od łańcucha, który jest pusty, będziesz musiał dodawać do niego znaki, aż łańcuch będzie taki sam, jak ten, którego chcemy. Możesz dodać znak na końcu łańcucha o koszcie x lub sklonować łańcuch o koszcie y. To, czego chcemy, to najtańszy sposób na zrobienie tego.

Przypadki testowe

targetString , appendcost, clonecost -> totalcost

"bb", 1, 2 -> 2
"bbbb", 2, 3 -> 7
"xzxpcxzxpy", 10, 11 -> 71
"abababab", 3, 5 -> 16
"abababab", 3, 11 -> 23

źródło
1
Jak definiowane są koszty? Czy są dodatnimi liczbami całkowitymi?
Arnauld,
1
Myślę, że chcesz po prostu rzucić wyzwanie kodowi golfowemu (najkrótszemu kodowi), więc usunąłem wyzwanie kodowe i programuję tagi układanki, które wskazują alternatywny sposób oceniania.
xnor
7
Myślę, że pomogłoby mieć więcej przypadków testowych, ponieważ wydaje się prawdopodobne, że ktoś mógłby napisać program o dobrej heurystyce, który działa dla wszystkich przypadków testowych, ale ogólnie nie jest optymalny. W szczególności żaden z przypadków testowych nie ma wielu klonów ani klonów podciągów, których nie ma na początku. Myślę, że dobrze byłoby mieć przykład, w którym zmiana tylko kosztów zmienia wydajność.
xnor
6
Nawiasem mówiąc, niezłe pierwsze wyzwanie!
Erik the Outgolfer,
Czy klonowanie pojedynczej litery jest nadal uważane za operację klonowania?
digEmAll,

Odpowiedzi:

2

Łuska , 25 bajtów

φ?ö▼z+:⁴∞²m⁰§:h§δf`€otṫḣ0

Wypróbuj online!

Dane wejściowe są w kolejności dodawania kosztu, kosztu klonowania, celu.

Wyjaśnienie

φ?ö▼z+:⁴∞²m⁰§:h§δf`€otṫḣ0  Two explicit inputs and one implicit.
                           Example: 2, 3, s="abab"
φ                          Make a recursive function and call it on s:
 ?                      0   If s is empty, return 0.
  ö▼z+:⁴∞²m⁰§:h§δf`€otṫḣ    Otherwise do this.
                       ḣ    Prefixes: ["a","ab","aba","abab"]
                    otṫ     Suffixes except the first one: ["bab","ab","b"]
               §δf`€        Keep those prefixes that have the corresponding suffix as substring: ["ab","aba"]
            §:h             Prepend s minus last character: ["aba","ab","aba"]
          m⁰                Recurse on each: x=[6,4,6]
        ∞²                  Repeat the clone cost: [3,3,3,..
      :⁴                    Prepend append cost: [2,3,3,3,..
    z+                      Add component-wise to x: [8,7,9]
   ▼                        Minimum: 7
Zgarb
źródło
1

Python 2 , 112 bajtów

f=lambda s,a,c,i=0:i<len(s)and min([a+f(s,a,c,i+1)]+[c+f(s,a,c,n)for n in range(i+1,len(s)+1)if s[i:n]in s[:i]])

Wypróbuj online!

ovs
źródło
1

JavaScript (ES6), 123 111 bajtów

Pobiera dane wejściowe jako (x)(y)(s).

x=>y=>m=g=([s,...r],o='',c=0)=>s?[...r,g(r,o+s,c+x)].map(_=>s+=r.shift(~o.search(s)&&g(r,o+s,c+y)))|m:m=m<c?m:c

Wypróbuj online!

Skomentował

x => y =>                    // x = 'append' cost; y = 'clone' cost
m =                          // m = minimum cost, initialized to a non-numeric value
                             //     this is what will eventually be returned
g = (                        // g = recursive function taking:
  [s,                        //   - the input string split into s = next character
      ...r],                 //     and r[] = array of remaining characters
  o = '',                    //   - o = output string
  c = 0                      //   - c = current cost
) =>                         //
  s ?                        // if s is defined:
    [ ...r,                  //   split a copy of r
      g(r, o + s, c + x)     //   do a recursive call with an 'append' operation
    ].map(_ =>               //   iterate as many times as there are remaining characters
                             //   in r[], + 1
      s +=                   //     append to s
        r.shift(             //     the next character picked from the beginning of r[]
          ~o.search(s) &&    //     if s is found in o,
          g(r, o + s, c + y) //     do a recursive call with a 'clone' operation
        )                    //     (note that both s and r are updated *after* the call)
    ) | m                    //   end of map(); return m
  :                          // else:
    m = m < c ? m : c        //   update m to min(m, c)
Arnauld
źródło
1

R , 192 185 bajtów

f=function(s,a,c,k=0,x="",R=substring,N=nchar,p=R(s,1,1:N(s)))'if'(!N(s),k,{y={};for(i in c(R(s,1,1),p[mapply(grepl,p,x)]))y=min(y,f(R(s,N(i)+1),a,c,k+'if'(any(y),c,a),paste0(x,i)));y})

Wypróbuj online!

Kod i objaśnienie:

# s is the current remaining string (at the beginning is equal to the target string)
# a is the append cost
# c is the clone cost
# k is the current cost (at the beginning is zero)
# x is the partially constructed string (at the beginning is empty)
f=function(s,a,c,k=0,x=""){
  # store in p all the possible prefixes of s
  p = substring(s,1,1:nchar(s))
  # if s is empty return the current cost k
  if(!nchar(s))
    k
  else{
    y={}
    # prepend the first letter of s (=append operation) to  
    # the prefixes in p that are contained in x (=clone operations)
    for(i in c(substring(s,1,1),p[mapply(grepl,p,x)])){
      # perform first the append then the clone operations and recurse, 
      # storing the cost in y if lower than previous
      # (if y is NULL is an append operation otherwise is a clone, we use the right costs)
      y = min(y,f(substring(s,nchar(i)+1),a,c,k+'if'(any(y),c,a),paste0(x,i)))
    }
    # return the current cost
    y
  }
}
digEmAll
źródło