#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> /* calloc(), free(), abs(), exit(), ... */
#include <limits.h> /* LONG_MAX */
/* safer free() ---------------------- */
#define FREE(p) \
do{ \
if ( (p) ) { \
free( (p) ); \
(p) = NULL; \
} \
}while(0)
/* safer fclose() -------------------- */
#define FCLOSE(fp) \
do { \
if ( (fp) ) { \
fclose((fp)); \
(fp) = NULL; \
} \
}while(0)
typedef struct MinSum0Pair {
long int small, large;
} MinSum0Pair;
/* --------------------------------------------------------------
* Create buffer 'buf' and fill-it up with the contents of the file 'fname'.
* Return the length of the buffer, or 0 on error.
* --------------------------------------------------------------
*/
long int buffer_make_fromfile( long int **buf, const char *fname )
{
FILE *fp = NULL;
long int i, buflen = 0;
if ( !fname || !buf ) {
puts( "*** error: invalid pointer!" ); goto ret_failure;
}
/* open input file */
if ( NULL
== (fp
=fopen(fname
, "r")) ) { puts( "*** error: cannot open input file!" ); goto ret_failure;
}
/* get the 1st number (buflen) and allocate so many long ints, in buf */
if ( 1 != fscanf(fp
, "%ld", &buflen
) ) { puts( "*** error: fscanf() failed!" ); goto ret_failure;
}
if ( NULL
== (*buf
=calloc(buflen
, sizeof(long int)) ) ) { puts( "*** error: out of memory!" ); goto ret_failure;
}
/* fill-in the buffer with the rest of long ints */
for (i
=0; !feof(fp
) && 1 == fscanf(fp
, "%ld", &(*buf
)[i
]); i
++ ) ; /* void */
FCLOSE(fp);
return buflen;
ret_failure:
FCLOSE(fp);
return 0;
}
/* --------------------------------------------------------------
* Print the first 'maxlen' elements of the buffer 'buf', separated be a space char.
* --------------------------------------------------------------
*/
void buffer_print( long int buf[], long int maxlen )
{
long int i = 0;
for (; i < maxlen; i++ )
return;
}
/* --------------------------------------------------------------
* Find in buffer 'buf' (of length 'buflen') the pair of values
* whose sum is closest to 0, and store them in '*pair'.
* Return false on error, true otherwise.
*
* Alg: Indexers 'istart' & 'iend' traverese 'buf' simultaneously, starting from its
* edges. Until they meet, they keep track of the minimum sum of pairs, along with
* the indicies that correspond to the members of the min pair ('ismall' & 'ilarge').
* --------------------------------------------------------------
*/
bool pair_minsum0( MinSum0Pair *pair, const long int buf[], long int buflen )
{
long int sum, minsum = LONG_MAX; /* current & minimum sums */
long int istart = 0, iend = buflen - 1; /* array indexers (start & end)*/
long int ismall = istart, ilarge = iend; /* pair's small & large indicies*/
if ( !pair || !buf ) {
puts( "*** error: invalid pointer!" ); goto ret_failure;
}
if ( buflen < 2 ) {
puts("*** error: insufficient data (must be more than 2 numbers)!"); goto ret_failure;
}
/* traverse the buffer simultaneously from both edges */
while ( istart < iend )
{
sum = buf[ istart ] + buf[ iend ];
/* get new minimum sum (if any) and update accordingly ismall & ilarge */
{
minsum = sum;
ismall = istart;
ilarge = iend;
}
if ( sum < 0 )
istart++;
else
iend--;
}
pair->small = buf[ ismall ];
pair->large = buf[ ilarge ];
return true;
ret_failure:
return false;
}
/* --------------------------------------------------------------
*
* --------------------------------------------------------------
*/
int main( void )
{
char fname[] = "op2.in";
long int *buf = NULL;
long int buflen = 0;
MinSum0Pair pair = { 0L, 0L };
/* read input-file contents into our buffer */
buflen = buffer_make_fromfile( &buf, fname );
if ( 0 == buflen )
goto ret_failure;
buffer_print( buf, buflen );
/* find & store the pair whose sum is closest to 0 */
if ( !pair_minsum0( &pair, buf, buflen) )
goto ret_failure;
printf( "%ld %ld\n", pair.
small, pair.
large );
FREE(buf);
ret_failure:
FREE(buf);
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRib29sLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4JCQkvKiBjYWxsb2MoKSwgZnJlZSgpLCBhYnMoKSwgZXhpdCgpLCAuLi4gKi8KI2luY2x1ZGUgPGxpbWl0cy5oPgkJCS8qIExPTkdfTUFYICovCgovKiBzYWZlciBmcmVlKCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwojZGVmaW5lIEZSRUUocCkJCQkJXAoJZG97CQkJCVwKCQlpZiAoIChwKSApIHsJCVwKCQkJZnJlZSggKHApICk7CVwKCQkJKHApID0gTlVMTDsJXAoJCX0JCQlcCgl9d2hpbGUoMCkKCi8qIHNhZmVyIGZjbG9zZSgpIC0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiNkZWZpbmUgRkNMT1NFKGZwKQkJCVwKCWRvIHsJCQkJXAoJCWlmICggKGZwKSApIHsJCVwKCQkJZmNsb3NlKChmcCkpOwlcCgkJCShmcCkgPSBOVUxMOwlcCgkJfQkJCVwKCX13aGlsZSgwKQoKdHlwZWRlZiBzdHJ1Y3QgTWluU3VtMFBhaXIgewoJbG9uZyBpbnQgc21hbGwsIGxhcmdlOwp9IE1pblN1bTBQYWlyOwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogQ3JlYXRlIGJ1ZmZlciAnYnVmJyBhbmQgZmlsbC1pdCB1cCB3aXRoIHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZSAnZm5hbWUnLgogKiBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyLCBvciAwIG9uIGVycm9yLgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KbG9uZyBpbnQgYnVmZmVyX21ha2VfZnJvbWZpbGUoIGxvbmcgaW50ICoqYnVmLCBjb25zdCBjaGFyICpmbmFtZSApCnsKCUZJTEUgKmZwID0gTlVMTDsKCWxvbmcgaW50IGksIGJ1ZmxlbiA9IDA7CgoJaWYgKCAhZm5hbWUgfHwgIWJ1ZiApIHsKCQlwdXRzKCAiKioqIGVycm9yOiBpbnZhbGlkIHBvaW50ZXIhIiApOwoJCWdvdG8gcmV0X2ZhaWx1cmU7Cgl9CgoJLyogb3BlbiBpbnB1dCBmaWxlICovCglpZiAoIE5VTEwgPT0gKGZwPWZvcGVuKGZuYW1lLCAiciIpKSApIHsKCQlwdXRzKCAiKioqIGVycm9yOiBjYW5ub3Qgb3BlbiBpbnB1dCBmaWxlISIgKTsKCQlnb3RvIHJldF9mYWlsdXJlOwoJfQoKCS8qIGdldCB0aGUgMXN0IG51bWJlciAoYnVmbGVuKSBhbmQgYWxsb2NhdGUgc28gbWFueSBsb25nIGludHMsIGluIGJ1ZiAqLwoJaWYgKCAxICE9IGZzY2FuZihmcCwgIiVsZCIsICZidWZsZW4pICkgewoJCXB1dHMoICIqKiogZXJyb3I6IGZzY2FuZigpIGZhaWxlZCEiICk7CgkJZ290byByZXRfZmFpbHVyZTsKCX0KCWlmICggTlVMTCA9PSAoKmJ1Zj1jYWxsb2MoYnVmbGVuLCBzaXplb2YobG9uZyBpbnQpKSApICkgewoJCXB1dHMoICIqKiogZXJyb3I6IG91dCBvZiBtZW1vcnkhIiApOwoJCWdvdG8gcmV0X2ZhaWx1cmU7Cgl9CgoJLyogZmlsbC1pbiB0aGUgYnVmZmVyIHdpdGggdGhlIHJlc3Qgb2YgbG9uZyBpbnRzICovCglmb3IgKGk9MDsgIWZlb2YoZnApICYmIDEgPT0gZnNjYW5mKGZwLCAiJWxkIiwgJigqYnVmKVtpXSk7IGkrKyApCgkJOyAvKiB2b2lkICovCgoJRkNMT1NFKGZwKTsKCXJldHVybiBidWZsZW47CgpyZXRfZmFpbHVyZToKCUZDTE9TRShmcCk7CglyZXR1cm4gMDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogUHJpbnQgdGhlIGZpcnN0ICdtYXhsZW4nIGVsZW1lbnRzIG9mIHRoZSBidWZmZXIgJ2J1ZicsIHNlcGFyYXRlZCBiZSBhIHNwYWNlIGNoYXIuCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwp2b2lkIGJ1ZmZlcl9wcmludCggbG9uZyBpbnQgYnVmW10sIGxvbmcgaW50IG1heGxlbiApCnsKCWxvbmcgaW50IGkgPSAwOwoJZm9yICg7IGkgPCBtYXhsZW47IGkrKyApCgkJcHJpbnRmKCAiJWxkICIsIGJ1ZltpXSApOwoJcHV0cygiXGIiKTsKCglyZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIEZpbmQgaW4gYnVmZmVyICdidWYnIChvZiBsZW5ndGggJ2J1ZmxlbicpIHRoZSBwYWlyIG9mIHZhbHVlcwogKiB3aG9zZSBzdW0gaXMgY2xvc2VzdCB0byAwLCBhbmQgc3RvcmUgdGhlbSBpbiAnKnBhaXInLgogKiBSZXR1cm4gZmFsc2Ugb24gZXJyb3IsIHRydWUgb3RoZXJ3aXNlLgogKgogKiBBbGc6IEluZGV4ZXJzICdpc3RhcnQnICYgJ2llbmQnIHRyYXZlcmVzZSAnYnVmJyBzaW11bHRhbmVvdXNseSwgc3RhcnRpbmcgZnJvbSBpdHMKICoJZWRnZXMuIFVudGlsIHRoZXkgbWVldCwgdGhleSBrZWVwIHRyYWNrIG9mIHRoZSBtaW5pbXVtIHN1bSBvZiBwYWlycywgYWxvbmcgd2l0aAogKiAJdGhlIGluZGljaWVzIHRoYXQgY29ycmVzcG9uZCB0byB0aGUgbWVtYmVycyBvZiB0aGUgbWluIHBhaXIgKCdpc21hbGwnICYgJ2lsYXJnZScpLgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KYm9vbCBwYWlyX21pbnN1bTAoIE1pblN1bTBQYWlyICpwYWlyLCBjb25zdCBsb25nIGludCBidWZbXSwgbG9uZyBpbnQgYnVmbGVuICkKewoJbG9uZyBpbnQgc3VtLCBtaW5zdW0gPSBMT05HX01BWDsJCS8qIGN1cnJlbnQgJiBtaW5pbXVtIHN1bXMgICAgICAqLwoJbG9uZyBpbnQgaXN0YXJ0ID0gMCwgaWVuZCA9IGJ1ZmxlbiAtIDE7CQkvKiBhcnJheSBpbmRleGVycyAoc3RhcnQgJiBlbmQpKi8KCWxvbmcgaW50IGlzbWFsbCA9IGlzdGFydCwgaWxhcmdlID0gaWVuZDsJLyogcGFpcidzIHNtYWxsICYgbGFyZ2UgaW5kaWNpZXMqLwoKCWlmICggIXBhaXIgfHwgIWJ1ZiApIHsKCQlwdXRzKCAiKioqIGVycm9yOiBpbnZhbGlkIHBvaW50ZXIhIiApOwoJCWdvdG8gcmV0X2ZhaWx1cmU7Cgl9CglpZiAoIGJ1ZmxlbiA8IDIgKSB7CgkJcHV0cygiKioqIGVycm9yOiBpbnN1ZmZpY2llbnQgZGF0YSAobXVzdCBiZSBtb3JlIHRoYW4gMiBudW1iZXJzKSEiKTsKCQlnb3RvIHJldF9mYWlsdXJlOwoJfQoKCS8qIHRyYXZlcnNlIHRoZSBidWZmZXIgc2ltdWx0YW5lb3VzbHkgZnJvbSBib3RoIGVkZ2VzICovCgl3aGlsZSAoIGlzdGFydCA8IGllbmQgKQoJewoJCXN1bSA9IGJ1ZlsgaXN0YXJ0IF0gKyBidWZbIGllbmQgXTsKCgkJLyogZ2V0IG5ldyBtaW5pbXVtIHN1bSAoaWYgYW55KSBhbmQgdXBkYXRlIGFjY29yZGluZ2x5IGlzbWFsbCAmIGlsYXJnZSAqLwoJCWlmICggYWJzKHN1bSkgPCBhYnMobWluc3VtKSApCgkJewoJCQltaW5zdW0gPSBzdW07CgkJCWlzbWFsbCA9IGlzdGFydDsKCQkJaWxhcmdlID0gaWVuZDsKCQl9CgkJaWYgKCBzdW0gPCAwICkKCQkJaXN0YXJ0Kys7CgkJZWxzZQoJCQlpZW5kLS07Cgl9CgoJcGFpci0+c21hbGwgPSBidWZbIGlzbWFsbCBdOwoJcGFpci0+bGFyZ2UgPSBidWZbIGlsYXJnZSBdOwoKCXJldHVybiB0cnVlOwoKcmV0X2ZhaWx1cmU6CglyZXR1cm4gZmFsc2U7Cn0KIAovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KaW50IG1haW4oIHZvaWQgKQp7CgljaGFyIAkJZm5hbWVbXSA9ICJvcDIuaW4iOwoJbG9uZyBpbnQgCSpidWYgCT0gTlVMTDsKCWxvbmcgaW50IAlidWZsZW4gCT0gMDsKCU1pblN1bTBQYWlyCXBhaXIgCT0geyAwTCwgMEwgfTsKCgkvKiByZWFkIGlucHV0LWZpbGUgY29udGVudHMgaW50byBvdXIgYnVmZmVyICovCglidWZsZW4gPSBidWZmZXJfbWFrZV9mcm9tZmlsZSggJmJ1ZiwgZm5hbWUgKTsKCWlmICggMCA9PSBidWZsZW4gKQoJCWdvdG8gcmV0X2ZhaWx1cmU7CglidWZmZXJfcHJpbnQoIGJ1ZiwgYnVmbGVuICk7CgoJLyogZmluZCAmIHN0b3JlIHRoZSBwYWlyIHdob3NlIHN1bSBpcyBjbG9zZXN0IHRvIDAgKi8KCWlmICggIXBhaXJfbWluc3VtMCggJnBhaXIsIGJ1ZiwgYnVmbGVuKSApCgkJZ290byByZXRfZmFpbHVyZTsKCglwcmludGYoICIlbGQgJWxkXG4iLCBwYWlyLnNtYWxsLCBwYWlyLmxhcmdlICk7CgoJRlJFRShidWYpOwoJZXhpdCggRVhJVF9TVUNDRVNTICk7CgpyZXRfZmFpbHVyZToKCUZSRUUoYnVmKTsKCWV4aXQoIEVYSVRfRkFJTFVSRSApOwp9Cg==