source: CIVL/examples/verifyThisProblems/lrs.c@ adcb43a

1.23 2.0 main test-branch
Last change on this file since adcb43a was 41eb9b6, checked in by Yihao Yan <yihaoyan1@…>, 10 years ago

format changing

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@3144 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 2.8 KB
Line 
1/*
2Author: Yihao
3
4Download LCP.zip from: http://fm2012.verifythis.org/challenges
5
6-----------------
7Problem description:
8
9This is a problem in 2012 as an advance problem for LCP
10Here is the description:
11Together with a suffix array, LCP can be used to solve interesting text
12problems, such as finding the longest repeated substring (LRS) in a text.
13
14A suffix array (for a given text) is an array of all suffixes of the
15text. For the text [7,8,8,6], the suffix array is
16[[7,8,8,6],
17 [8,8,6],
18 [8,6],
19 [6]]
20
21Typically, the suffixes are not stored explicitly as above but
22represented as pointers into the original text. The suffixes in a suffix
23array are sorted in lexicographical order. This way, occurrences of
24repeated substrings in the original text are neighbors in the suffix
25array.
26
27For the above, example (assuming pointers are 0-based integers), the
28sorted suffix array is:
29[3,0,2,1]
30
31-----------------
32Verification task:
33
34Implement the lrs function, and verify that it behaves in the way described above.
35
36command: civl verify lrs.c
37
38result: the problem is solved
39*/
40
41#include <stdlib.h>
42#include <stdio.h>
43#include <civlc.cvh>
44#include <assert.h>
45
46$input int N_BOUND = 4;
47$input int N;
48$input int X1[N];
49$assume (N < N_BOUND && N >= 0);
50
51int lcp1(int *arr, int n, int x, int y){
52 int l=0;
53
54 while (x+l<n && y+l<n && arr[x+l]==arr[y+l]) {
55 l++;
56 }
57 return l;
58}
59
60int compare(int *a, int n, int x, int y) {
61 if (x == y) return 0;
62 int l = 0;
63
64 while (x+l<n && y+l<n && a[x+l] == a[y+l]) {
65 l++;
66 }
67
68 if (x+l == n) return -1;
69 if (y+l == n) return 1;
70 if (a[x+l] < a[y+l]) return -1;
71 if (a[x+l] > a[y+l]) return 1;
72
73 return -2;
74}
75
76void sort(int *a, int n, int *data) {
77 for(int i = 0; i < n + 0; i++) {
78 for(int j = i; j > 0 && compare(a, n, data[j - 1], data[j]) > 0; j--) {
79 int b = j - 1;
80 int t = data[j];
81
82 data[j] = data[b];
83 data[b] = t;
84 }
85 }
86}
87
88int lcp2(int *a, int n, int index, int* suffixes){
89 return lcp1(a,n,suffixes[index], suffixes[index-1]);
90}
91
92/**
93result[0]: index
94result[1]: length
95*/
96void lrs(int* a, int n, int *result){
97 int suffixes[n];
98
99 for(int i=0; i<n; i++){
100 suffixes[i] = i;
101 }
102 sort(a, n, suffixes);
103 for(int i=1; i<n; i++){
104 int len = lcp2(a, n, i,suffixes);
105
106 if(len > result[1]){
107 result[0] = suffixes[i];
108 result[1] = len;
109 }
110 }
111}
112
113int main(){
114 int* result = (int*)malloc(2* sizeof(int));
115
116 result[0] = 0;
117 result[1] = 0;
118 lrs(X1, N, result);
119
120 int index = result[0];
121 int maxLen = result[1];
122
123 if(N > 1){
124 $assert($exists {int k | k >= 0 && k <= N - maxLen && k != index}(
125 $forall {i = 0 .. maxLen-1} X1[k+i] == X1[index+i]
126 ));
127 }else{
128 $assert(index == 0 && maxLen == 0);
129 }
130 free(result);
131 return 0;
132}
Note: See TracBrowser for help on using the repository browser.