BudiBadu Logo

Celestial Pattern Synthesis

Dynamic Programming Hard 0 views
Like2

In Celestial Pattern Synthesis you must build a target mural string using available snippets each with a cost Snippets may be reused and may overlap as long as every placed character matches the mural exactly The primary objective is minimum total cost If multiple constructions share that minimum cost you must return the lexicographically smallest sequence of snippet indices according to the required build order A practical model is shortest path DP over mural positions State i means prefix length i already built A transition exists when a snippet matches starting at i moving to i len snippet with added cost Besides cost track reconstruction metadata for index-sequence tie-breaking For equal-cost alternatives compare candidate sequences lexicographically and keep the smaller one If position N is unreachable return cost 1 with an empty sequence The judge checks tie situations impossible builds and repeated snippet use Correctness depends on both numeric optimality and exact sequence ordering not just feasibility Keep transitions strict on character matching and maintain deterministic tie resolution This hard challenge combines string matching graph-style DP and stable lexicographic decision logic in one optimization pipeline In practice this means storing both best cost and a comparable representation of the chosen index sequence for each position state Tie-breaking cannot be an afterthought if sequence order is not enforced during transitions you can get correct cost but wrong official output ordering When the task involves connectivity or route cost build adjacency carefully

Examples

Example 1
Input
mural = "ababa", snippets = [("ab",3),("aba",4),("ba",2)]
Output
cost = 6, sequence = [2, 3]
Explanation

Example 1: Minimal cost solution using snippets at indices 2 and 3

Example 2
Input
mural = "aaaa", snippets = [("aa",3),("a",2)]
Output
cost = 6, sequence = [2, 2, 2, 2]
Explanation

Example 2: Using snippet at index 2 four times

Example 3
Input
mural = "abc", snippets = [("ac",5),("bc",4)]
Output
cost = -1, sequence = []
Explanation

Example 3: No valid solution exists

Algorithm Flow

Recommendation Algorithm Flow for Celestial Pattern Synthesis - Budibadu
Recommendation Algorithm Flow for Celestial Pattern Synthesis - Budibadu

Best Answers

java
import java.util.*;

class Solution {
    public Object[] celestial_pattern_synthesis(String mural, List<Object[]> snippets) {
        if (mural == null || mural.isEmpty()) return new Object[]{0L, new ArrayList<Integer>()};
        int N = mural.length();
        int M = snippets.size();
        List<Occ>[] occurrences = new List[M];
        for (int i = 0; i < M; i++) {
            occurrences[i] = new ArrayList<>();
            String pat = (String) snippets.get(i)[0];
            int start = 0;
            while ((start = mural.indexOf(pat, start)) != -1) {
                occurrences[i].add(new Occ(start, start + pat.length()));
                start++;
            }
        }
        long[] dp = new long[N + 1];
        Arrays.fill(dp, Long.MAX_VALUE);
        dp[N] = 0;
        List<Match>[] byEnd = new List[N + 1];
        for (int i = 0; i <= N; i++) byEnd[i] = new ArrayList<>();
        for (int i = 0; i < M; i++) {
            int cost = ((Number) snippets.get(i)[1]).intValue();
            for (Occ occ : occurrences[i]) byEnd[occ.end].add(new Match(occ.start, cost));
        }
        PriorityQueue<PQItem> pq = new PriorityQueue<>((a, b) -> Long.compare(a.val, b.val));
        for (int i = N; i > 0; i--) {
            if (dp[i] != Long.MAX_VALUE) {
                for (Match m : byEnd[i]) pq.add(new PQItem(m.cost + dp[i], m.start));
            }
            while (!pq.isEmpty() && pq.peek().start > i - 1) pq.poll();
            if (!pq.isEmpty()) dp[i - 1] = pq.peek().val;
        }
        if (dp[0] == Long.MAX_VALUE) return new Object[]{-1L, new ArrayList<Integer>()};
        List<Integer> resSeq = new ArrayList<>();
        int curr = 0;
        while (curr < N) {
            int bestIdx = Integer.MAX_VALUE;
            int bestEnd = -1;
            for (int j = 0; j < M; j++) {
                int cost = ((Number) snippets.get(j)[1]).intValue();
                int idx = j + 1;
                if (idx > bestIdx) continue;
                for (Occ occ : occurrences[j]) {
                    if (occ.start <= curr && occ.end > curr) {
                        if (dp[occ.end] != Long.MAX_VALUE && cost + dp[occ.end] == dp[curr]) {
                            if (idx < bestIdx) {
                                bestIdx = idx;
                                bestEnd = occ.end;
                            } else {
                                bestEnd = Math.max(bestEnd, occ.end);
                            }
                            break;
                        }
                    }
                }
            }
            resSeq.add(bestIdx);
            curr = bestEnd;
        }
        return new Object[]{dp[0], resSeq};
    }
    static class Occ { int start, end; Occ(int s, int e) { start = s; end = e; } }
    static class Match { int start, cost; Match(int s, int c) { start = s; cost = c; } }
    static class PQItem { long val; int start; PQItem(long v, int s) { val = v; start = s; } }
}