import java.io.* ;
import java.util.Arrays ;
import java.util.HashSet ;
import java.util.List ;
import java.util.Scanner ;
import java.util.Set ;
import java.util.Iterator ;
import static java.
lang .
System .
*;
class Ideone {
// userResults variables are where we write output we want the user to see
// it functions just like System.out
// Readable -- via toString() -- version of userResults
// Writable -- via println("") -- version of userResults
// numberOfTests is incremented whenever a test case is evaluated
private int numberOfTests = 0 ;
// numberOfTestsPassed is incremented whenever a test case is evaluated successfully
private int numberOfTestsPassed = 0 ;
//(Integer) ((numberOfTestsPassed / numberOfTests)*100) == percent correct for student work
// Class autorun entry point
new Ideone( ) .test ( ) ;
}
// Put tests for specific template here
List< String> input;
List< String> output;
// **** Add/edit test cases here ****
input
= Arrays .
asList ( "34" ,
"\n " ,
"45" ,
"\n " ,
"55" ,
"\n " ,
"57" ,
"\n " ,
"79" ,
"\n " ,
"67" ,
"\n " ,
"68" ,
"\n " ,
"69" ,
"\n " ,
"72" ,
"\n " ,
"77" ,
"\n " ,
"88" ,
"\n " ,
"99" ,
"\n " ,
"101" ,
"\n " ,
"2345" ,
"\n " ,
"-10" ,
"\n " ,
"200" ,
"\n " ,
"200" ,
"\n " ,
"200" ,
"\n " ,
"200" ,
"\n " ,
"200" ,
"\n " ,
"-200" ,
"\n " ) ; output
= Arrays .
asList ( "Enter the values for the first array, up to 10000 values, enter a negative number to quit" ,
"" ,
"First Array" ,
"34 45 55 57 79 67 68 69 72 77 88 99 101 2345" ,
"Second Array" ,
"200 200 200 200 200" ,
"ERROR: Array not in correct order" ) ; assertRegex( "Test:error" , input, output) ;
input
= Arrays .
asList ( "12" ,
"\n " ,
"23" ,
"\n " ,
"34" ,
"\n " ,
"45" ,
"\n " ,
"56" ,
"\n " ,
"67" ,
"\n " ,
"78" ,
"\n " ,
"89" ,
"\n " ,
"90" ,
"\n " ,
"-100" ,
"21" ,
"\n " ,
"32" ,
"\n " ,
"43" ,
"\n " ,
"54" ,
"\n " ,
"65" ,
"\n " ,
"76" ,
"\n " ,
"87" ,
"\n " ,
"98" ,
"\n " ,
"100" ,
"\n " ,
"-1" ,
"\n " ) ; output
= Arrays .
asList ( "Enter the values for the first array, up to 10000 values, enter a negative number to quit" ,
"" ,
"First Array" ,
"12 23 34 45 56 67 78 89 90" ,
"Second Array" ,
"21 32 43 54 65 76 87 98 100" ,
"12 21 23 32 34 43 45 54 56 65 67 76 78 87 89 90 98 100" ) ; assertRegex( "Test:ok" , input, output) ;
generateScoreResults( ) ;
}
// Scoring Utilities
private void generateScoreResults( ) {
System .
out .
println ( "Your code has been evaluated against a set of test data." ) ; System .
out .
format ( "You had %d out of %d tests pass correctly.\r \n " ,
numberOfTestsPassed, numberOfTests) ;
System .
out .
format ( "Your score is %d%%.\r \n " , calculateScore
( ) ) ; // Share any messages from assertions about pass/fail on specific tests
System .
out .
print ( userResultsByteArray.
toString ( ) ) ; System .
out .
format ( "Secrets: {\" score\" : %d}\r \n " , calculateScore
( ) ) ;
}
private int calculateScore( ) {
double passed = ( double ) numberOfTestsPassed;
double taken = ( double ) numberOfTests;
return ( int ) ( ( passed / taken ) * 100 ) ;
}
// Assertion/Testing Utilities
// assertRegex will run the student's code, providing "inputs" as STDIN
// It will regex match the output generated by the student's code
// against the values provided in expectedList
// Preserve StdOut
// redirect StdOut
// Inject test data into StdIn
setStdIn( inputs) ;
// Run student code w/inputs
// Eval expected results against stub System.out (byteArray)
Scanner scanner = new Scanner( actuals.toString ( ) ) ;
// Loop through actual results, and look for matches with expected results
// Remove expected value once it is found
userResults.println ( testName) ;
int numberOfTestCases = 1 ;
try {
for ( int i = 0 ; i < expectedList.size ( ) ; i++ ) {
numberOfTests++;
String expected
= expectedList.
get ( i
) ; while ( scanner.hasNextLine ( ) ) {
String actual
= scanner.
nextLine ( ) ; if ( actual.matches ( ".*" + expected+ ".*" ) ) {
numberOfTestsPassed++;
matched = true ;
userResults.println ( " Case #" + numberOfTestCases+ " passed" ) ;
// we replace the matched item with a regex /.\A/ which matches nothing
// this is to prevent this expectation from matching another actual line of output
expectedList.set ( i, ".\\ A" ) ;
// break once we find a match for this test case, we don't want to match any more
break ;
} // if (actual..
} // while (scanner..
if ( ! matched) {
userResults.println ( " Case #" + numberOfTestCases+ " failed" ) ;
}
// reset scanner for next operation
scanner = new Scanner( actuals.toString ( ) ) ;
numberOfTestCases++;
} // for (int i=...
} finally {
//restore StdOut
}
}
// assertNotMatch will run the student's code, providing "inputs" as STDIN
// It will make sure that NONE of the output values provided in expectedList are found in ANY of the actual output
// Print test name to user
userResults.println ( testName) ;
// Preserve StdOut
// redirect StdOut
// Inject test data into StdIn
setStdIn( inputs) ;
// Run student code w/inputs
// Load test output into scanner
Scanner scanner = new Scanner( actuals.toString ( ) ) ;
// Loop through test output (actuals), and look for matches with expected results
// Fail test if a match is found
int numberOfTestCases = 1 ;
try {
for ( int i = 0 ; i < expectedList.size ( ) ; i++ ) {
numberOfTests++;
String expected
= expectedList.
get ( i
) ; while ( scanner.hasNextLine ( ) ) {
String actual
= scanner.
nextLine ( ) ; if ( actual.matches ( ".*" + expected+ ".*" ) ) {
userResults.println ( " Case #" + numberOfTestCases+ " failed" ) ;
passed = false ;
// break b/c this test case has failed and no further lines need to be examined
break ;
} // if (actual..
} // while (scanner..
if ( passed) {
numberOfTestsPassed++;
userResults.println ( " Case #" + numberOfTestCases+ " passed" ) ;
}
// reset scanner for next operation
scanner = new Scanner( actuals.toString ( ) ) ;
numberOfTestCases++;
} // for (int i=...
} finally {
//restore StdOut
}
}
//Standard In/Out Utilities
// Sets StdOut to a new ByteStream
// Returns the ByteStream so whatever is written
// can be read back out later via this object
return newStdOutByteArray;
}
// set System.in/STDIN to string: newIn
// Note: be sure to preserve System.in before calling, if you need it later
// You can preserve System.in simply with InputStream oldIn = System.in;
private void setStdIn( List< String> listIn) {
String strIn
= joinCR
( listIn
) ; }
// Basic Utilities
//joins string list together w/carriage returns
private String joinCR
( List
< String
> list
) { return join( list, '\n ' ) ;
}
//join a list into a delimted string
private String join
( List
< String
> list,
char delimiter
) { StringBuilder sb = new StringBuilder( ) ;
sb.append ( s) .append ( delimiter) ;
}
sb.deleteCharAt ( sb.length ( ) - 1 ) ;
return sb.toString ( ) ;
}
} //Ideone class
// Following line needs to be uncommented and system swaps in student code
// in its place when run within GCB by code-runner system
//$$YIELD$$
class Main {
/*
While Loops
Tracing Code and Counting the Number of Iterations
More Loops
Technique - flag variables
Strings as class types (vs primitive)
*/
//WildCard
//assume only one * per string
Scanner scan
= new Scanner
( System .
in ) ;
//length will be less than 10,000
//count how many elements entered into each array
int a1 = 0 ;
int a2 = 0 ;
int ar1[ ] = new int [ 10000 ] ;
int ar2[ ] = new int [ 10000 ] ;
for ( int i= 0 ; i< ar1.length ; i++ )
{
}
int val = 1 ;
System .
out .
println ( "\n \n Enter the values for the first array, up to 10000 values, enter a negative number to quit" ) ; while ( val >= 0 )
{
val = scan.nextInt ( ) ;
if ( val >= 0 )
{
ar1[ a1] = val;
a1++;
}
}
//enter 2nd array
val = 1 ;
System .
out .
println ( "\n \n Enter the values for the second array, up to 10000 values, enter a negative number to quit" ) ; while ( val >= 0 )
{
val = scan.nextInt ( ) ;
if ( val >= 0 )
{
ar2[ a2] = val;
a2++;
}
}
System .
out .
println ( "\n \n First Array: " ) ; for ( int i = 0 ; i < a1; i++ )
System .
out .
print ( ar1
[ i
] + " " ) ;
System .
out .
println ( "\n \n Second Array: " ) ; for ( int i = 0 ; i < a2; i++ )
System .
out .
print ( ar2
[ i
] + " " ) ;
//check if in order
boolean inOrder = true ;
for ( int i = 1 ; i < a1; i++ )
{
if ( ar1[ i- 1 ] > ar1[ i] )
inOrder = false ;
}
for ( int i = 1 ; i < a2; i++ )
{
if ( ar2[ i- 1 ] > ar2[ i] )
inOrder = false ;
}
// System.out.println("\n\nIn order?? " + inOrder);
if ( ! inOrder)
{
System .
out .
println ( "\n \n ERROR: Array not in correct order" ) ; }
else
{
//merge and output
int merge [ ] = new int [ a1 + a2] ;
//System.out.println("\n\nLength of new array: " + merge.length);
a1 = 0 ;
a2 = 0 ;
for ( int i = 0 ; i < merge.length ; i++ )
{
if ( ar1[ a1] <= ar2[ a2] )
{
merge[ i] = ar1[ a1] ;
a1++;
}
else
{
merge[ i] = ar2[ a2] ;
a2++;
}
}
System .
out .
println ( "\n \n Merged Array: " ) ; for ( int i = 0 ; i < merge.length ; i++ )
System .
out .
print ( merge
[ i
] + " " ) ; }
}
}
aW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuSGFzaFNldDsKaW1wb3J0IGphdmEudXRpbC5MaXN0OwppbXBvcnQgamF2YS51dGlsLlNjYW5uZXI7CmltcG9ydCBqYXZhLnV0aWwuU2V0OwppbXBvcnQgamF2YS51dGlsLkl0ZXJhdG9yOwoKaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuU3lzdGVtLio7CgpjbGFzcyBJZGVvbmUgewogIC8vIHVzZXJSZXN1bHRzIHZhcmlhYmxlcyBhcmUgd2hlcmUgd2Ugd3JpdGUgb3V0cHV0IHdlIHdhbnQgdGhlIHVzZXIgdG8gc2VlCiAgLy8gaXQgZnVuY3Rpb25zIGp1c3QgbGlrZSBTeXN0ZW0ub3V0CgogIC8vIFJlYWRhYmxlIC0tIHZpYSB0b1N0cmluZygpIC0tIHZlcnNpb24gb2YgdXNlclJlc3VsdHMKICBwcml2YXRlIE91dHB1dFN0cmVhbSB1c2VyUmVzdWx0c0J5dGVBcnJheSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKICAvLyBXcml0YWJsZSAtLSB2aWEgcHJpbnRsbigiIikgLS0gdmVyc2lvbiBvZiB1c2VyUmVzdWx0cwogIHByaXZhdGUgUHJpbnRTdHJlYW0gdXNlclJlc3VsdHMgPSBuZXcgUHJpbnRTdHJlYW0odXNlclJlc3VsdHNCeXRlQXJyYXkpOwogIC8vIG51bWJlck9mVGVzdHMgaXMgaW5jcmVtZW50ZWQgd2hlbmV2ZXIgYSB0ZXN0IGNhc2UgaXMgZXZhbHVhdGVkCiAgcHJpdmF0ZSBpbnQgbnVtYmVyT2ZUZXN0cyA9IDA7CiAgLy8gbnVtYmVyT2ZUZXN0c1Bhc3NlZCBpcyBpbmNyZW1lbnRlZCB3aGVuZXZlciBhIHRlc3QgY2FzZSBpcyBldmFsdWF0ZWQgc3VjY2Vzc2Z1bGx5CiAgcHJpdmF0ZSBpbnQgbnVtYmVyT2ZUZXN0c1Bhc3NlZCA9IDA7CiAgLy8oSW50ZWdlcikgKChudW1iZXJPZlRlc3RzUGFzc2VkIC8gbnVtYmVyT2ZUZXN0cykqMTAwKSA9PSBwZXJjZW50IGNvcnJlY3QgZm9yIHN0dWRlbnQgd29yawoKICAvLyBDbGFzcyBhdXRvcnVuIGVudHJ5IHBvaW50CiAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgdGhyb3dzIEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewogICAgbmV3IElkZW9uZSgpLnRlc3QoKTsKICB9CgogIC8vIFB1dCB0ZXN0cyBmb3Igc3BlY2lmaWMgdGVtcGxhdGUgaGVyZQogIHByaXZhdGUgdm9pZCB0ZXN0KCkgdGhyb3dzIEV4Y2VwdGlvbiwgSU9FeGNlcHRpb24gewoKICAgIExpc3Q8U3RyaW5nPiBpbnB1dDsKICAgIExpc3Q8U3RyaW5nPiBvdXRwdXQ7CgogICAgLy8gKioqKiBBZGQvZWRpdCB0ZXN0IGNhc2VzIGhlcmUgKioqKgogICAgaW5wdXQgPSBBcnJheXMuYXNMaXN0KCIzNCIsIlxuIiwiNDUiLCJcbiIsIjU1IiwiXG4iLCI1NyIsIlxuIiwiNzkiLCJcbiIsIjY3IiwiXG4iLCI2OCIsIlxuIiwiNjkiLCJcbiIsIjcyIiwiXG4iLCI3NyIsIlxuIiwiODgiLCJcbiIsIjk5IiwiXG4iLCIxMDEiLCJcbiIsIjIzNDUiLCJcbiIsIi0xMCIsIlxuIiwiMjAwIiwiXG4iLCIyMDAiLCJcbiIsIjIwMCIsIlxuIiwiMjAwIiwiXG4iLCIyMDAiLCJcbiIsIi0yMDAiLCJcbiIpOwogICAgb3V0cHV0ID0gQXJyYXlzLmFzTGlzdCgiRW50ZXIgdGhlIHZhbHVlcyBmb3IgdGhlIGZpcnN0IGFycmF5LCB1cCB0byAxMDAwMCB2YWx1ZXMsIGVudGVyIGEgbmVnYXRpdmUgbnVtYmVyIHRvIHF1aXQiLCIiLCJGaXJzdCBBcnJheSIsICIzNCA0NSA1NSA1NyA3OSA2NyA2OCA2OSA3MiA3NyA4OCA5OSAxMDEgMjM0NSIsICJTZWNvbmQgQXJyYXkiLCAiMjAwIDIwMCAyMDAgMjAwIDIwMCIsICJFUlJPUjogQXJyYXkgbm90IGluIGNvcnJlY3Qgb3JkZXIiKTsKICAgIGFzc2VydFJlZ2V4KCJUZXN0OmVycm9yIiwgaW5wdXQsIG91dHB1dCk7CgogICAgaW5wdXQgPSBBcnJheXMuYXNMaXN0KCIxMiIsIlxuIiwiMjMiLCJcbiIsIjM0IiwiXG4iLCI0NSIsIlxuIiwiNTYiLCJcbiIsIjY3IiwiXG4iLCI3OCIsIlxuIiwiODkiLCJcbiIsIjkwIiwiXG4iLCItMTAwIiwiMjEiLCJcbiIsIjMyIiwiXG4iLCI0MyIsIlxuIiwiNTQiLCJcbiIsIjY1IiwiXG4iLCI3NiIsIlxuIiwiODciLCJcbiIsIjk4IiwiXG4iLCIxMDAiLCJcbiIsIi0xIiwiXG4iKTsKICAgIG91dHB1dCA9IEFycmF5cy5hc0xpc3QoIkVudGVyIHRoZSB2YWx1ZXMgZm9yIHRoZSBmaXJzdCBhcnJheSwgdXAgdG8gMTAwMDAgdmFsdWVzLCBlbnRlciBhIG5lZ2F0aXZlIG51bWJlciB0byBxdWl0IiwiIiwiRmlyc3QgQXJyYXkiLCAiMTIgMjMgMzQgNDUgNTYgNjcgNzggODkgOTAiLCAiU2Vjb25kIEFycmF5IiwgIjIxIDMyIDQzIDU0IDY1IDc2IDg3IDk4IDEwMCIsICIxMiAyMSAyMyAzMiAzNCA0MyA0NSA1NCA1NiA2NSA2NyA3NiA3OCA4NyA4OSA5MCA5OCAxMDAiKTsKICAgIGFzc2VydFJlZ2V4KCJUZXN0Om9rIiwgaW5wdXQsIG91dHB1dCk7CgogICAgZ2VuZXJhdGVTY29yZVJlc3VsdHMoKTsKCiAgfQoKICAvLyBTY29yaW5nIFV0aWxpdGllcwogIHByaXZhdGUgdm9pZCBnZW5lcmF0ZVNjb3JlUmVzdWx0cygpewogICAgU3lzdGVtLm91dC5wcmludGxuKCJZb3VyIGNvZGUgaGFzIGJlZW4gZXZhbHVhdGVkIGFnYWluc3QgYSBzZXQgb2YgdGVzdCBkYXRhLiIpOwogICAgU3lzdGVtLm91dC5mb3JtYXQoIllvdSBoYWQgJWQgb3V0IG9mICVkIHRlc3RzIHBhc3MgY29ycmVjdGx5LlxyXG4iLAogICAgICAgIG51bWJlck9mVGVzdHNQYXNzZWQsIG51bWJlck9mVGVzdHMpOwogICAgU3lzdGVtLm91dC5mb3JtYXQoIllvdXIgc2NvcmUgaXMgJWQlJS5cclxuIiwgY2FsY3VsYXRlU2NvcmUoKSk7CiAgICAvLyBTaGFyZSBhbnkgbWVzc2FnZXMgZnJvbSBhc3NlcnRpb25zIGFib3V0IHBhc3MvZmFpbCBvbiBzcGVjaWZpYyB0ZXN0cwogICAgU3lzdGVtLm91dC5wcmludCh1c2VyUmVzdWx0c0J5dGVBcnJheS50b1N0cmluZygpKTsKICAgIFN5c3RlbS5vdXQuZm9ybWF0KCJTZWNyZXRzOiB7XCJzY29yZVwiOiAlZH1cclxuIiwgY2FsY3VsYXRlU2NvcmUoKSk7CgogIH0KCiAgcHJpdmF0ZSBpbnQgY2FsY3VsYXRlU2NvcmUoKXsKICAgIGRvdWJsZSBwYXNzZWQgPSAoZG91YmxlKSBudW1iZXJPZlRlc3RzUGFzc2VkOwogICAgZG91YmxlIHRha2VuID0gKGRvdWJsZSkgbnVtYmVyT2ZUZXN0czsKICAgIHJldHVybiAoaW50KSAoKCBwYXNzZWQgLyB0YWtlbiApKjEwMCk7CiAgfQoKICAvLyBBc3NlcnRpb24vVGVzdGluZyBVdGlsaXRpZXMKCiAgLy8gYXNzZXJ0UmVnZXggd2lsbCBydW4gdGhlIHN0dWRlbnQncyBjb2RlLCBwcm92aWRpbmcgImlucHV0cyIgYXMgU1RESU4KICAvLyBJdCB3aWxsIHJlZ2V4IG1hdGNoIHRoZSBvdXRwdXQgZ2VuZXJhdGVkIGJ5IHRoZSBzdHVkZW50J3MgY29kZQogIC8vIGFnYWluc3QgdGhlIHZhbHVlcyBwcm92aWRlZCBpbiBleHBlY3RlZExpc3QKICBwcml2YXRlIHZvaWQgYXNzZXJ0UmVnZXgoU3RyaW5nIHRlc3ROYW1lLCBMaXN0PFN0cmluZz4gaW5wdXRzLCBMaXN0PFN0cmluZz4gZXhwZWN0ZWRMaXN0KSB0aHJvd3MgRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CiAgICAvLyBQcmVzZXJ2ZSBTdGRPdXQKICAgIFByaW50U3RyZWFtIG9yaWdPdXQgPSBTeXN0ZW0ub3V0OwogICAgLy8gcmVkaXJlY3QgU3RkT3V0CiAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYWN0dWFscyA9IHNldFN0ZE91dCgpOwogICAgLy8gSW5qZWN0IHRlc3QgZGF0YSBpbnRvIFN0ZEluCiAgICBzZXRTdGRJbihpbnB1dHMpOwogICAgLy8gUnVuIHN0dWRlbnQgY29kZSB3L2lucHV0cwogICAgTWFpbi5tYWluKG5ldyBTdHJpbmdbMF0pOwogICAgLy8gRXZhbCBleHBlY3RlZCByZXN1bHRzIGFnYWluc3Qgc3R1YiBTeXN0ZW0ub3V0IChieXRlQXJyYXkpCiAgICBTY2FubmVyIHNjYW5uZXIgPSBuZXcgU2Nhbm5lcihhY3R1YWxzLnRvU3RyaW5nKCkpOwogICAgLy8gTG9vcCB0aHJvdWdoIGFjdHVhbCByZXN1bHRzLCBhbmQgbG9vayBmb3IgbWF0Y2hlcyB3aXRoIGV4cGVjdGVkIHJlc3VsdHMKICAgIC8vIFJlbW92ZSBleHBlY3RlZCB2YWx1ZSBvbmNlIGl0IGlzIGZvdW5kCiAgICB1c2VyUmVzdWx0cy5wcmludGxuKHRlc3ROYW1lKTsKCiAgICBpbnQgbnVtYmVyT2ZUZXN0Q2FzZXMgPSAxOwogICAgdHJ5IHsKICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBleHBlY3RlZExpc3Quc2l6ZSgpOyBpKyspewogICAgICAgIG51bWJlck9mVGVzdHMrKzsKICAgICAgICBCb29sZWFuIG1hdGNoZWQgPSBmYWxzZTsKICAgICAgICBTdHJpbmcgZXhwZWN0ZWQgPSBleHBlY3RlZExpc3QuZ2V0KGkpOwogICAgICAgIHdoaWxlIChzY2FubmVyLmhhc05leHRMaW5lKCkpewogICAgICAgICAgU3RyaW5nIGFjdHVhbCA9IHNjYW5uZXIubmV4dExpbmUoKTsKICAgICAgICAgIGlmIChhY3R1YWwubWF0Y2hlcygiLioiK2V4cGVjdGVkKyIuKiIpKSB7CiAgICAgICAgICAgIG51bWJlck9mVGVzdHNQYXNzZWQrKzsKICAgICAgICAgICAgbWF0Y2hlZCA9IHRydWU7CiAgICAgICAgICAgIHVzZXJSZXN1bHRzLnByaW50bG4oIiAgQ2FzZSAjIitudW1iZXJPZlRlc3RDYXNlcysiIHBhc3NlZCIpOwogICAgICAgICAgICAvLyB3ZSByZXBsYWNlIHRoZSBtYXRjaGVkIGl0ZW0gd2l0aCBhIHJlZ2V4IC8uXEEvIHdoaWNoIG1hdGNoZXMgbm90aGluZwogICAgICAgICAgICAvLyB0aGlzIGlzIHRvIHByZXZlbnQgdGhpcyBleHBlY3RhdGlvbiBmcm9tIG1hdGNoaW5nIGFub3RoZXIgYWN0dWFsIGxpbmUgb2Ygb3V0cHV0CiAgICAgICAgICAgIGV4cGVjdGVkTGlzdC5zZXQoaSwgIi5cXEEiKTsKICAgICAgICAgICAgLy8gYnJlYWsgb25jZSB3ZSBmaW5kIGEgbWF0Y2ggZm9yIHRoaXMgdGVzdCBjYXNlLCB3ZSBkb24ndCB3YW50IHRvIG1hdGNoIGFueSBtb3JlCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfSAvLyBpZiAoYWN0dWFsLi4KICAgICAgICB9IC8vIHdoaWxlIChzY2FubmVyLi4KICAgICAgICBpZiAoIW1hdGNoZWQpewogICAgICAgICAgdXNlclJlc3VsdHMucHJpbnRsbigiICBDYXNlICMiK251bWJlck9mVGVzdENhc2VzKyIgZmFpbGVkIik7CiAgICAgICAgfQogICAgICAgIC8vIHJlc2V0IHNjYW5uZXIgZm9yIG5leHQgb3BlcmF0aW9uCiAgICAgICAgc2Nhbm5lciA9IG5ldyBTY2FubmVyKGFjdHVhbHMudG9TdHJpbmcoKSk7CiAgICAgICAgbnVtYmVyT2ZUZXN0Q2FzZXMrKzsKICAgICAgfSAvLyBmb3IgKGludCBpPS4uLgogICAgfSBmaW5hbGx5IHsKICAgICAgLy9yZXN0b3JlIFN0ZE91dAogICAgICBTeXN0ZW0uc2V0T3V0KG9yaWdPdXQpOwogICAgfQogIH0KCiAgLy8gYXNzZXJ0Tm90TWF0Y2ggd2lsbCBydW4gdGhlIHN0dWRlbnQncyBjb2RlLCBwcm92aWRpbmcgImlucHV0cyIgYXMgU1RESU4KICAvLyBJdCB3aWxsIG1ha2Ugc3VyZSB0aGF0IE5PTkUgb2YgdGhlIG91dHB1dCB2YWx1ZXMgcHJvdmlkZWQgaW4gZXhwZWN0ZWRMaXN0IGFyZSBmb3VuZCBpbiBBTlkgb2YgdGhlIGFjdHVhbCBvdXRwdXQKICBwcml2YXRlIHZvaWQgYXNzZXJ0Tm90TWF0Y2goU3RyaW5nIHRlc3ROYW1lLCBMaXN0PFN0cmluZz4gaW5wdXRzLCBMaXN0PFN0cmluZz4gZXhwZWN0ZWRMaXN0KSB0aHJvd3MgRXhjZXB0aW9uLCBJT0V4Y2VwdGlvbiB7CiAgICAvLyBQcmludCB0ZXN0IG5hbWUgdG8gdXNlcgogICAgdXNlclJlc3VsdHMucHJpbnRsbih0ZXN0TmFtZSk7CiAgICAvLyBQcmVzZXJ2ZSBTdGRPdXQKICAgIFByaW50U3RyZWFtIG9yaWdPdXQgPSBTeXN0ZW0ub3V0OwogICAgLy8gcmVkaXJlY3QgU3RkT3V0CiAgICBCeXRlQXJyYXlPdXRwdXRTdHJlYW0gYWN0dWFscyA9IHNldFN0ZE91dCgpOwogICAgLy8gSW5qZWN0IHRlc3QgZGF0YSBpbnRvIFN0ZEluCiAgICBzZXRTdGRJbihpbnB1dHMpOwogICAgLy8gUnVuIHN0dWRlbnQgY29kZSB3L2lucHV0cwogICAgTWFpbi5tYWluKG5ldyBTdHJpbmdbMF0pOwogICAgLy8gTG9hZCB0ZXN0IG91dHB1dCBpbnRvIHNjYW5uZXIKICAgIFNjYW5uZXIgc2Nhbm5lciA9IG5ldyBTY2FubmVyKGFjdHVhbHMudG9TdHJpbmcoKSk7CgogICAgLy8gTG9vcCB0aHJvdWdoIHRlc3Qgb3V0cHV0IChhY3R1YWxzKSwgYW5kIGxvb2sgZm9yIG1hdGNoZXMgd2l0aCBleHBlY3RlZCByZXN1bHRzCiAgICAvLyBGYWlsIHRlc3QgaWYgYSBtYXRjaCBpcyBmb3VuZAogICAgaW50IG51bWJlck9mVGVzdENhc2VzID0gMTsKICAgIHRyeSB7CiAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgZXhwZWN0ZWRMaXN0LnNpemUoKTsgaSsrKXsKICAgICAgICBudW1iZXJPZlRlc3RzKys7CiAgICAgICAgQm9vbGVhbiBwYXNzZWQgPSB0cnVlOwogICAgICAgIFN0cmluZyBleHBlY3RlZCA9IGV4cGVjdGVkTGlzdC5nZXQoaSk7CiAgICAgICAgd2hpbGUgKHNjYW5uZXIuaGFzTmV4dExpbmUoKSl7CiAgICAgICAgICBTdHJpbmcgYWN0dWFsID0gc2Nhbm5lci5uZXh0TGluZSgpOwogICAgICAgICAgaWYgKGFjdHVhbC5tYXRjaGVzKCIuKiIrZXhwZWN0ZWQrIi4qIikpIHsKICAgICAgICAgICAgdXNlclJlc3VsdHMucHJpbnRsbigiICBDYXNlICMiK251bWJlck9mVGVzdENhc2VzKyIgZmFpbGVkIik7CiAgICAgICAgICAgIHBhc3NlZCA9IGZhbHNlOwogICAgICAgICAgICAvLyBicmVhayBiL2MgdGhpcyB0ZXN0IGNhc2UgaGFzIGZhaWxlZCBhbmQgbm8gZnVydGhlciBsaW5lcyBuZWVkIHRvIGJlIGV4YW1pbmVkCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfSAvLyBpZiAoYWN0dWFsLi4KICAgICAgICB9IC8vIHdoaWxlIChzY2FubmVyLi4KICAgICAgICBpZiAocGFzc2VkKXsKICAgICAgICAgIG51bWJlck9mVGVzdHNQYXNzZWQrKzsKICAgICAgICAgIHVzZXJSZXN1bHRzLnByaW50bG4oIiAgQ2FzZSAjIitudW1iZXJPZlRlc3RDYXNlcysiIHBhc3NlZCIpOwogICAgICAgIH0KICAgICAgICAvLyByZXNldCBzY2FubmVyIGZvciBuZXh0IG9wZXJhdGlvbgogICAgICAgIHNjYW5uZXIgPSBuZXcgU2Nhbm5lcihhY3R1YWxzLnRvU3RyaW5nKCkpOwogICAgICAgIG51bWJlck9mVGVzdENhc2VzKys7CiAgICAgIH0gLy8gZm9yIChpbnQgaT0uLi4KICAgIH0gZmluYWxseSB7CiAgICAgIC8vcmVzdG9yZSBTdGRPdXQKICAgICAgU3lzdGVtLnNldE91dChvcmlnT3V0KTsKICAgIH0KICB9CgoKICAvL1N0YW5kYXJkIEluL091dCBVdGlsaXRpZXMKCiAgLy8gU2V0cyBTdGRPdXQgdG8gYSBuZXcgQnl0ZVN0cmVhbQogIC8vIFJldHVybnMgdGhlIEJ5dGVTdHJlYW0gc28gd2hhdGV2ZXIgaXMgd3JpdHRlbgogIC8vIGNhbiBiZSByZWFkIGJhY2sgb3V0IGxhdGVyIHZpYSB0aGlzIG9iamVjdAogIHByaXZhdGUgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIHNldFN0ZE91dCgpewogICAgQnl0ZUFycmF5T3V0cHV0U3RyZWFtIG5ld1N0ZE91dEJ5dGVBcnJheSA9IG5ldyBCeXRlQXJyYXlPdXRwdXRTdHJlYW0oKTsKICAgIFByaW50U3RyZWFtIG5ld1N0ZE91dCA9IG5ldyBQcmludFN0cmVhbShuZXdTdGRPdXRCeXRlQXJyYXkpOwogICAgU3lzdGVtLnNldE91dChuZXdTdGRPdXQpOwogICAgcmV0dXJuIG5ld1N0ZE91dEJ5dGVBcnJheTsKICB9CgogIC8vIHNldCBTeXN0ZW0uaW4vU1RESU4gdG8gc3RyaW5nOiBuZXdJbgogIC8vIE5vdGU6IGJlIHN1cmUgdG8gcHJlc2VydmUgU3lzdGVtLmluIGJlZm9yZSBjYWxsaW5nLCBpZiB5b3UgbmVlZCBpdCBsYXRlcgogIC8vIFlvdSBjYW4gcHJlc2VydmUgU3lzdGVtLmluIHNpbXBseSB3aXRoIElucHV0U3RyZWFtIG9sZEluID0gU3lzdGVtLmluOwogIHByaXZhdGUgdm9pZCBzZXRTdGRJbihMaXN0PFN0cmluZz4gbGlzdEluKXsKICAgIFN0cmluZyBzdHJJbiA9IGpvaW5DUihsaXN0SW4pOwogICAgQnl0ZUFycmF5SW5wdXRTdHJlYW0gc3R1YkluID0gbmV3IEJ5dGVBcnJheUlucHV0U3RyZWFtKHN0ckluLmdldEJ5dGVzKCkpOwogICAgU3lzdGVtLnNldEluKHN0dWJJbik7CiAgfQoKICAvLyBCYXNpYyBVdGlsaXRpZXMKICAvL2pvaW5zIHN0cmluZyBsaXN0IHRvZ2V0aGVyIHcvY2FycmlhZ2UgcmV0dXJucwogIHByaXZhdGUgU3RyaW5nIGpvaW5DUihMaXN0PFN0cmluZz4gbGlzdCl7CiAgICByZXR1cm4gam9pbihsaXN0LCAnXG4nKTsKICB9CgogIC8vam9pbiBhIGxpc3QgaW50byBhIGRlbGltdGVkIHN0cmluZwogIHByaXZhdGUgU3RyaW5nIGpvaW4oTGlzdDxTdHJpbmc+IGxpc3QsIGNoYXIgZGVsaW1pdGVyKXsKICAgIFN0cmluZ0J1aWxkZXIgc2IgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgZm9yKFN0cmluZyBzOiBsaXN0KSB7CiAgICAgICBzYi5hcHBlbmQocykuYXBwZW5kKGRlbGltaXRlcik7CiAgICB9CiAgICBzYi5kZWxldGVDaGFyQXQoc2IubGVuZ3RoKCktMSk7CiAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICB9Cgp9Ly9JZGVvbmUgY2xhc3MKCi8vIEZvbGxvd2luZyBsaW5lIG5lZWRzIHRvIGJlIHVuY29tbWVudGVkIGFuZCBzeXN0ZW0gc3dhcHMgaW4gc3R1ZGVudCBjb2RlCi8vIGluIGl0cyBwbGFjZSB3aGVuIHJ1biB3aXRoaW4gR0NCIGJ5IGNvZGUtcnVubmVyIHN5c3RlbQoKLy8kJFlJRUxEJCQKCmNsYXNzIE1haW4gewogIC8qCiAgIFdoaWxlIExvb3BzCiAgIFRyYWNpbmcgQ29kZSBhbmQgQ291bnRpbmcgdGhlIE51bWJlciBvZiBJdGVyYXRpb25zCiAgIE1vcmUgTG9vcHMKICAgVGVjaG5pcXVlIC0gZmxhZyB2YXJpYWJsZXMKICAgU3RyaW5ncyBhcyBjbGFzcyB0eXBlcyAodnMgcHJpbWl0aXZlKQogICAqLwoJICAvL1dpbGRDYXJkCiAgICAvL2Fzc3VtZSBvbmx5IG9uZSAqIHBlciBzdHJpbmcKCgkgcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZyBzdHJbXSkgdGhyb3dzIElPRXhjZXB0aW9uIHsKCiAgICAgICAgIFNjYW5uZXIgc2NhbiA9IG5ldyBTY2FubmVyIChTeXN0ZW0uaW4pOwoKICAgICAgICAgLy9sZW5ndGggd2lsbCBiZSBsZXNzIHRoYW4gMTAsMDAwCiAgICAgICAgIC8vY291bnQgaG93IG1hbnkgZWxlbWVudHMgZW50ZXJlZCBpbnRvIGVhY2ggYXJyYXkKICAgICAgICAgaW50IGExID0gMDsKICAgICAgICAgaW50IGEyID0gMDsKICAgICAgICAgaW50IGFyMVtdID0gbmV3IGludCBbMTAwMDBdOwogICAgICAgICBpbnQgYXIyW10gPSBuZXcgaW50IFsxMDAwMF07CgogICAgICAgICBmb3IgKGludCBpPTA7IGk8IGFyMS5sZW5ndGg7IGkrKykKICAgICAgICAgewogICAgICAgICAgICAgIGFyMVtpXSA9IEludGVnZXIuTUFYX1ZBTFVFOwogICAgICAgICAgICAgIGFyMltpXSA9IEludGVnZXIuTUFYX1ZBTFVFOwogICAgICAgICB9CgogICAgICAgICBpbnQgdmFsID0xOwogICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlxuXG5FbnRlciB0aGUgdmFsdWVzIGZvciB0aGUgZmlyc3QgYXJyYXksIHVwIHRvIDEwMDAwIHZhbHVlcywgZW50ZXIgYSBuZWdhdGl2ZSBudW1iZXIgdG8gcXVpdCIpOwogICAgICAgICB3aGlsZSAodmFsID49IDApCiAgICAgICAgIHsKICAgICAgICAgICAgICB2YWwgPSBzY2FuLm5leHRJbnQoKTsKICAgICAgICAgICAgICBpZiAodmFsID49IDApCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgYXIxW2ExXSA9IHZhbDsKICAgICAgICAgICAgICAgICAgIGExKys7CiAgICAgICAgICAgICAgfQogICAgICAgICB9CgoKCiAgICAgICAgIC8vZW50ZXIgMm5kIGFycmF5CiAgICAgICAgIHZhbCA9MTsKICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblxuRW50ZXIgdGhlIHZhbHVlcyBmb3IgdGhlIHNlY29uZCBhcnJheSwgdXAgdG8gMTAwMDAgdmFsdWVzLCBlbnRlciBhIG5lZ2F0aXZlIG51bWJlciB0byBxdWl0Iik7CiAgICAgICAgIHdoaWxlICh2YWwgPj0gMCkKICAgICAgICAgewogICAgICAgICAgICAgIHZhbCA9IHNjYW4ubmV4dEludCgpOwogICAgICAgICAgICAgIGlmICh2YWwgPj0gMCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICBhcjJbYTJdID0gdmFsOwogICAgICAgICAgICAgICAgICAgYTIrKzsKICAgICAgICAgICAgICB9CiAgICAgICAgIH0KCiAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cbkZpcnN0IEFycmF5OiAiKTsKICAgICAgICAgZm9yIChpbnQgaSA9MDsgaSA8IGExOyBpKyspCiAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChhcjFbaV0gKyAiICIpOwoKICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblxuU2Vjb25kIEFycmF5OiAiKTsKICAgICAgICAgZm9yIChpbnQgaSA9MDsgaSA8IGEyOyBpKyspCiAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludChhcjJbaV0gKyAiICIpOwoKCgoKICAgICAgICAgLy9jaGVjayBpZiBpbiBvcmRlcgogICAgICAgICBib29sZWFuIGluT3JkZXIgPSB0cnVlOwoKICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBhMTsgaSsrKQogICAgICAgICB7CiAgICAgICAgICAgICAgaWYgKGFyMVtpLTFdID4gYXIxW2ldKQogICAgICAgICAgICAgICAgICAgaW5PcmRlciA9IGZhbHNlOwogICAgICAgICB9CiAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDwgYTI7IGkrKykKICAgICAgICAgewogICAgICAgICAgICAgIGlmIChhcjJbaS0xXSA+IGFyMltpXSkKICAgICAgICAgICAgICAgICAgIGluT3JkZXIgPSBmYWxzZTsKICAgICAgICAgfQovLyAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cbkluIG9yZGVyPz8gIiArIGluT3JkZXIpOwoKCiAgICAgICAgIGlmICghaW5PcmRlcikKICAgICAgICAgewogICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiXG5cbkVSUk9SOiBBcnJheSBub3QgaW4gY29ycmVjdCBvcmRlciIpOwogICAgICAgICB9CiAgICAgICAgIGVsc2UKICAgICAgICAgewoKICAgICAgICAgICAgICAvL21lcmdlIGFuZCBvdXRwdXQKICAgICAgICAgICAgICBpbnQgbWVyZ2UgW10gPSBuZXcgaW50IFthMSArIGEyXTsKICAgICAgICAgICAgICAvL1N5c3RlbS5vdXQucHJpbnRsbigiXG5cbkxlbmd0aCBvZiBuZXcgYXJyYXk6ICIgKyBtZXJnZS5sZW5ndGgpOwogICAgICAgICAgICAgIGExID0gMDsKICAgICAgICAgICAgICBhMiA9IDA7CiAgICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBtZXJnZS5sZW5ndGg7IGkrKykKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICBpZiAoYXIxW2ExXSA8PSBhcjJbYTJdKQogICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBtZXJnZVtpXSA9IGFyMVthMV07CiAgICAgICAgICAgICAgICAgICAgICAgIGExKys7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlW2ldID0gYXIyW2EyXTsKICAgICAgICAgICAgICAgICAgICAgICAgYTIrKzsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJcblxuTWVyZ2VkIEFycmF5OiAiKTsKICAgICAgICAgICAgICBmb3IgKGludCBpID0wOyBpIDwgbWVyZ2UubGVuZ3RoOyBpKyspCiAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50KG1lcmdlW2ldICsgIiAiKTsKICAgICAgICAgfQogICAgIH0KCn0=